根据这些发行说明,Json.NET 现在支持 SerializableAttribute:
Json.NET 现在检测具有 SerializableAttribute 的类型,并序列化该类型上的所有字段(公共和私有),并忽略这些属性。
我有以下抛出JsonSerializationException
的示例代码:
从"CS$<>9__CachedAnonymousMethodDelegate1"获取值时出错 "控制台应用程序1.MyType"。
如果我注释 TotalWithLambda 属性,则序列化将按预期成功。事实上,我得到以下结果:
- 离开 [Serializable],离开 TotalWithLambda:抛出 JsonSerializationException
- 保留 [可序列化],删除 TotalWithLambda:仅序列化"myList"
- 删除 [Serializable],保留 TotalWithLambda:序列化 "myList"、"Total" 和 "TotalWithLambda" 删除
- [可序列化],删除 TotalWithLambda:序列化"myList"和"Total"
我了解所有这些情况,除了第一个。为什么 [可序列化] 和包含 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); } }
}
}
我安装并使用了 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 尝试序列化私有字段,但不能,因为它的类型为 Func<int, int>
。删除 SerializableAttribute 会指示 Json.NET 忽略私有字段,因此不会导致问题。
更新:Json.NET 4.5 版本 3 现在仅在显式设置IgnoreSerializableAttribute=false
时才会出现此问题,或者可以通过将JsonObjectAttribute
添加到类来解决。
默认将 IgnoreSerializableAttribute 更改为 true,这撤消了第 2 版中引入的重大更改 - http://json.codeplex.com/releases/view/85975
您可以在此处阅读有关它的更多信息 - http://json.codeplex.com/discussions/351981