2016-05-25 38 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

相關問題