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] 和带有 lambda 的只读属性的组合会导致此异常?

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,发现当 lambda 未注释时,编译器会在类中添加一个字段和一个方法:

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 回答