3

これらのリリース ノートによると、Json.NET は SerializableAttribute をサポートするようになりました。

Json.NET は、SerializableAttribute を持つ型を検出し、その型のすべてのフィールド (パブリックとプライベートの両方) をシリアル化し、プロパティを無視するようになりました。

をスローする次のサンプル コードがありますJsonSerializationException

「ConsoleApplication1.MyType」の「CS$<>9__CachedAnonymousMethodDelegate1」から値を取得中にエラーが発生しました。

TotalWithLambda プロパティにコメントを付けると、シリアル化は期待どおりに成功します。実際、次の結果が得られます。

  • [Serializable] のまま、TotalWithLambda のまま: JsonSerializationException をスロー
  • [Serializable] のまま、TotalWithLambda を削除: 「myList」のみをシリアル化します
  • [Serializable] を削除し、TotalWithLambda を残す: "myList"、"Total"、および "TotalWithLambda" をシリアル化します。
  • [Serializable] を削除し、TotalWithLambda を削除: 「myList」と「Total」をシリアル化します

最初のケースを除いて、これらすべてのケースを理解しています。[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); } }
    }

}
4

2 に答える 2

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 はプライベート フィールドをシリアル化しようとしますが、 type であるためできませんFunc<int, int>。SerializableAttribute を削除すると、Json.NET はプライベート フィールドを無視するように指示されるため、問題は発生しません。

更新: Json.NET 4.5 リリース 3 では、明示的に を設定した場合にのみ問題が発生するようになりました。または、クラスに をIgnoreSerializableAttribute=false追加することで解決できます。JsonObjectAttribute

于 2012-04-13T18:29:15.437 に答える
2

リリース 3 で IgnoreSerializableAttribute をデフォルトで true に変更しました。これにより、リリース 2 で導入された重大な変更が取り消されます - http://json.codeplex.com/releases/view/85975

ここで詳細を読むことができます - http://json.codeplex.com/discussions/351981

于 2012-04-13T21:46:40.450 に答える