2016-05-25 6 views
7

時々表示される文字<のため、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 
    } 
}) 
+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#のオブジェクトをシリアル化するために何も確実な方法はありません。

代わりに、あなたはあなたの問題を攻撃するいくつかの方法があります:Json.NETトレース上

  1. 電源を入れます。 Debugging with Serialization Tracingを参照してください。これは、オブジェクトグラフのどこに問題が発生しているかを示すはずです。

  2. むしろあなたがJsonSerializer.Serialize()でシリアライズしStringWriterを包むJsonTextWriterを使用して文字列に書き込む場合、JsonConvert.SerializeObject()でシリアライズよりも、あなたはライターをフラッシュし、部分的なシリアライズを記録することができます。それは問題がどこで発生するかをいくらか考えているかもしれません。

  3. 他のさまざまなシリアライザを使用してシリアル化を試みることができます。もしあれば、結果を記録してください。

  4. オブジェクトプロパティの1つが例外をスローしている場合は、代わりにフィールドのシリアル化を強制することがあります。 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); 
     } 
    } 
} 

をあなたはおそらくJsonSerializerExtensions.SerializeObject(data)JsonConvert.SerializeObject(data)を置き換え、その後、適切な伐採方法で最終Debug.WriteLine()に代わりますあなたのアプリケーションのコードで。

+0

この質問/回答はメタについて議論されています:http://meta.stackoverflow.com/questions/323819/someone-immediately-answered-my-question-with-a-very-useful-response-i-Want-it – user000001

関連する問題