2016-05-25 32 views
7

由于字符<不时出现,我遇到了我的JSON序列化程序随机失败的问题。我不能确定这是从哪里来的,我想 - 在例外情况下 - 使用不同的方法重新进行串行化,以便我可以看到有问题的对象的完整表示。有没有办法做到这一点?如何将ANY对象序列化为字符串?

我当前的代码:

// 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 
    } 
}) 
+0

那么你可以试试['JavaScriptSerializer'](https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer%28v=vs.110%29.aspx)。你是否有完整的'ToString()'异常输出,包括消息和回溯? – dbc

+0

[使用序列化跟踪进行调试](http://www.newtonsoft.com/json/help/html/SerializationTracing.htm)可能会有所帮助。 – dbc

回答

18

有序列化任何和一切可能的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()用适当的测井方法,然后用JsonSerializerExtensions.SerializeObject(data)取代JsonConvert.SerializeObject(data)在你的应用代码中。

+0

这个问题/答案已经在meta上讨论过:http://meta.stackoverflow.com/questions/323819/someone-immediately-answered-my-question-with-a-very-useful-response-i-want-it – user000001

相关问题