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

我遇到了一个问题,我的JSON序列化程序由于字符<不时出现而随机失败。 我无法确定这是从哪里来的,我想 – 在例外 – 使用不同的方法重新编译,以便我可以看到有问题的对象的完整表示。 有没有办法做到这一点?

我目前的代码:

 // 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跟踪。 请参见使用序列化跟踪进行调试 。 这应该告诉您对象图中问题发生的位置。

  2. 如果使用JsonSerializer.Serialize()序列化并使用包装StringWriterJsonTextWriter写入字符串,则可以刷新writer并记录部分序列化,而不是使用JsonConvert.SerializeObject()序列化。 这可能会让人知道问题出在哪里。

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

  4. 如果您的某个对象属性抛出exception,则可能会尝试强制字段序列化。 请参阅JSON.Net:强制序列化所有私有字段和子类中的所有字段 。

例如,将#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(this string xmlString) { using (StringReader reader = new StringReader(xmlString)) { return (T)new XmlSerializer(typeof(T)).Deserialize(reader); } } public static string GetXml(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 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(string data) { return FromBase64String(data, null); } public static T FromBase64String(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() ,然后在应用程序代码中用JsonSerializerExtensions.SerializeObject(data)替换JsonConvert.SerializeObject(data)