gpt4 book ai didi

c# - 如何将任何对象序列化为字符串?

转载 作者:太空狗 更新时间:2023-10-29 19:55:39 28 4
gpt4 key购买 nike

我遇到了一个问题,我的 JSON 序列化程序由于字符 < 而随机失败不时出现。我无法确定这是从哪里来的,我想——在异常(exception)情况下——使用不同的方法重新序列化,这样我就可以看到有问题的对象的完整表示。有什么办法吗?

我当前的代码:

// data is of type 'object'
serialized = JsonConvert.SerializeObject(data, new JsonSerializerSettings() {
Error = delegate(object sender, ErrorEventArgs args) {
// reserialize here and output object so I know what the heck is going on
}
})

最佳答案

没有万无一失的方法来序列化所有可能的 C# 对象。

相反,您有几种方法来解决您的问题:

  1. 启用 Json.NET 跟踪。参见 Debugging with Serialization Tracing .这应该会告诉您问题发生在对象图中的哪个位置。

  2. 而不是用 JsonConvert.SerializeObject() 序列化, 如果你用 JsonSerializer.Serialize() 序列化并使用 JsonTextWriter 写入字符串包装 StringWriter ,您可以刷新编写器并记录部分序列化。这可能会让您了解问题出在哪里。

  3. 您可以尝试使用其他各种序列化程序进行序列化,如果可行,请记录结果。

  4. 如果您的某个对象属性抛出异常,您可能会尝试强制对字段进行序列化。参见 JSON.Net: Force serialization of all private fields and all fields in sub-classes .

例如,将#1、#2 和#3 放在一起给出以下方法:

public static class JsonSerializerExtensions
{
public static string SerializeObject(object obj, JsonSerializerSettings settings = null)
{
settings = settings ?? new JsonSerializerSettings();

var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
using (var jsonWriter = new JsonTextWriter(writer))
{
var oldError = settings.Error;
var oldTraceWriter = settings.TraceWriter;
var oldFormatting = settings.Formatting;
try
{
settings.Formatting = Newtonsoft.Json.Formatting.Indented;
if (settings.TraceWriter == null)
settings.TraceWriter = new MemoryTraceWriter();
settings.Error = oldError + delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
jsonWriter.Flush();

var logSb = new StringBuilder();
logSb.AppendLine("Serialization error: ");
logSb.Append("Path: ").Append(args.ErrorContext.Path).AppendLine();
logSb.Append("Member: ").Append(args.ErrorContext.Member).AppendLine();
logSb.Append("OriginalObject: ").Append(args.ErrorContext.OriginalObject).AppendLine();
logSb.AppendLine("Error: ").Append(args.ErrorContext.Error).AppendLine();
logSb.AppendLine("Partial serialization results: ").Append(sb).AppendLine();
logSb.AppendLine("TraceWriter contents: ").Append(settings.TraceWriter).AppendLine();

logSb.AppendLine("JavaScriptSerializer serialization: ");
try
{
logSb.AppendLine(new JavaScriptSerializer().Serialize(obj));
}
catch (Exception ex)
{
logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
}

logSb.AppendLine("XmlSerializer serialization: ");
try
{
logSb.AppendLine(obj.GetXml());
}
catch (Exception ex)
{
logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
}

logSb.AppendLine("BinaryFormatter serialization: ");
try
{
logSb.AppendLine(BinaryFormatterExtensions.ToBase64String(obj));
}
catch (Exception ex)
{
logSb.AppendLine("Failed, error: ").AppendLine(ex.ToString());
}

Debug.WriteLine(logSb);
};
var serializer = JsonSerializer.CreateDefault(settings);
serializer.Serialize(jsonWriter, obj);
}
finally
{
settings.Error = oldError;
settings.TraceWriter = oldTraceWriter;
settings.Formatting = oldFormatting;
}
}

return sb.ToString();
}
}

public static class XmlSerializerExtensions
{
public static T LoadFromXML<T>(this string xmlString)
{
using (StringReader reader = new StringReader(xmlString))
{
return (T)new XmlSerializer(typeof(T)).Deserialize(reader);
}
}

public static string GetXml<T>(this T obj)
{
using (var textWriter = new StringWriter())
{
var settings = new XmlWriterSettings() { Indent = true, IndentChars = " " };
using (var xmlWriter = XmlWriter.Create(textWriter, settings))
new XmlSerializer(obj.GetType()).Serialize(xmlWriter, obj);
return textWriter.ToString();
}
}
}

public static class BinaryFormatterExtensions
{
public static string ToBase64String<T>(T obj)
{
using (var stream = new MemoryStream())
{
new BinaryFormatter().Serialize(stream, obj);
return Convert.ToBase64String(stream.GetBuffer(), 0, checked((int)stream.Length)); // Throw an exception on overflow.
}
}

public static T FromBase64String<T>(string data)
{
return FromBase64String<T>(data, null);
}

public static T FromBase64String<T>(string data, BinaryFormatter formatter)
{
using (var stream = new MemoryStream(Convert.FromBase64String(data)))
{
formatter = (formatter ?? new BinaryFormatter());
var obj = formatter.Deserialize(stream);
if (obj is T)
return (T)obj;
return default(T);
}
}
}

您可能会替换最后的 Debug.WriteLine()使用适当的日志记录方法,然后替换 JsonConvert.SerializeObject(data)JsonSerializerExtensions.SerializeObject(data)在您的应用程序代码中。

关于c# - 如何将任何对象序列化为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37448604/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com