2012-04-13 11 views
2

these release notesによると、Json.NETは今SerializableAttributeをサポートしています。なぜJson.NETのシリアル化は[シリアル化可能]で、ラムダは読み取り専用のプロパティで失敗するのですか?

Json.NETは今SerializableAttributeを持っているタイプを検出し、その種類にすべてのフィールドをシリアル化し、パブリックとプライベートの両方、およびプロパティを無視します。

私はJsonSerializationExceptionをスローし、次のサンプルコードがあります。

'ConsoleApplication1.MyType' オン 'CS $ <> 9__CachedAnonymousMethodDelegate1' から取得時にエラーが発生しました値を。

私がTotalWithLambdaプロパティにコメントすると、シリアライズは正常に成功します。実際に、私は次のような結果を得る:

  • まま[直列化]を、TotalWithLambdaを残す:JsonSerializationException
  • まま[直列化]をスローし、TotalWithLambdaを削除:だけ
  • がままに、[直列化]を削除 "はmyList" をシリアライズTotalWithLambdaは: "はmyList"、 "トータル"、および "TotalWithLambda"
  • 削除[直列化]をシリアライズし、TotalWithLambdaを削除することは:私は番目のすべてを理解して "はmyList" と "合計"

をシリアライズ最初のもの以外の場合。 [Serializable]とそれにラムダを持つ読み取り専用プロパティの組み合わせがこの例外を引き起こすのはなぜですか?

namespace ConsoleApplication1 
{ 
    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using Newtonsoft.Json; 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var foo = new MyType(); 
      foo.myList = new List<int>() { 0, 1, 2, 3 }; 

      var returnVal = JsonConvert.SerializeObject(foo); 

      Console.WriteLine("Return: " + returnVal.ToString()); 
      Console.ReadKey(); 
     } 
    } 

    [Serializable] 
    class MyType 
    { 
     public IList<int> myList; 
     public int Total { get { return this.myList.Sum(); } } 
     public int TotalWithLambda { get { return this.myList.Sum(x => x); } } 
    } 

} 

答えて

3

は、私がインストールしてJustDecompileを使用し、ラムダがコメント解除されている場合、コンパイラは、フィールドとクラスにメソッドを追加することがわかった:

public class MyType 
{ 
    [CompilerGenerated] 
    private static Func<int, int> CS$<>9__CachedAnonymousMethodDelegate1; 

    [CompilerGenerated] 
    private static int <get_TotalWithLambda>b__0(int x) { ... } 

    // ... plus the other class members ... 
} 

クラスがそれにSerializableAttributeを持っている場合は、Json.NETプライベートフィールドのシリアル化を試みますが、タイプがFunc<int, int>であるためできません。 SerializableAttributeを削除すると、Json.NETはプライベートフィールドを無視するように指示するため、問題は発生しません。

更新:あなたが明示的にIgnoreSerializableAttribute=falseを設定するか、それがクラスにJsonObjectAttributeを追加することで解決できる場合 Json.NET 4.5リリース3は今、この唯一の問題になります。..

+0

[JsonObject]属性を追加するには、私のために働きました。 – shookdiesel

2

私はにIgnoreSerializableAttributeを変更しましたリリース2で導入された破断変更元に戻すリリース3でデフォルトでtrue - http://json.codeplex.com/releases/view/85975

をあなたがここでそれについての詳細を読むことができます - http://json.codeplex.com/discussions/351981

+0

ちょうど2セントの価値:私はIgnoreSerializableAttributeがデフォルトでfalseであることを好みます。これは、Assertion Json.NET特有のAsp.Netシリアル化属性に一貫しているためです。私は、私がクラスを改装したり、直列化エンジンを切り替えただけでDefaultContractResolverの設定を変更する必要がないように感じます。私はJson.NETに切り替えました。これは、VS2013のプロジェクトテンプレートに含まれています。これは、MSからデファクトスタンダードに推薦されたものです。私はJson時に迷惑になりました。以前はXMLのシリアル化が機能していたときにNETシリアル化が失敗しました。 – subsci

関連する問題