为什么JSON .Net不能序列化静态或const成员变量?

我无法在任何地方找到答案,但是当我尝试使用static或const成员变量序列化结构或类时,默认情况下它们不会序列化。 如果我尝试通过设置MemberSerialization.OptIn强制序列化,我收到一个错误。

恩。

 [JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] public int x = 1; [JsonProperty] public static int y = 2; } 

如果我尝试使用以下命令序列化此类:

 Test t = new Test(); string s = JsonConvert.SerializeObject( t ); 

我收到错误Error getting value from 'y' on 'Test' 。 如果y是const,也会发生同样的情况。

我的理论是静态和const值存储在内存中特殊的地方,并且由于某种原因,Json序列化器试图访问它们。 这完全是一种预感,我在C#Reference for Static中看不到任何帮助。 我对C#比较陌生 – 在这一点上,这真的是一个好奇的问题。

如果想要,它当然可以序列化静态变量。 通过使用Reflection API检查对象和类型来完成序列化,这些API允许您执行“任何操作” – 没有技术原因这些值无法序列化。

然而,有一个合乎逻辑的理由不支持默认情况:它没有多大意义。 您正在序列化一个实例staticconst成员在逻辑上不是实例的一部分,而是整个类的一部分。

也就是说,如果它是属性,你仍然可以序列化static成员:

 [JsonProperty] public static int y { get; set; } // this will be serialized 

当然,您可以通过创建自定义JsonConverter来完全覆盖序列化程序的行为。

从Json.NET 6.0.4开始,静态和const成员变量以及静态属性在用[JsonProperty]标记时将被序列化。 从发行说明 :

  • 修复 – 修复了序列化静态字段

因此序列化以下类:

 [JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] int x = 1; [JsonProperty] static int y = 2; [JsonProperty] const int z = 333; } 

产生{"x":1,"y":2,"z":333} 。 示例小提琴 。

试试这个:

 using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; public static string SerializeStaticClass(System.Type a_Type) { var TypeBlob = a_Type.GetFields().ToDictionary(x => x.Name, x => x.GetValue(null)); return JsonConvert.SerializeObject(TypeBlob); } 

我这样做是为了将所有静态类常量序列化为JS文件,然后将该文件捆绑到一个角度应用程序中。 将生成的js对象附加到$ rootScope,所有角度代码都可以访问常量。

帽子提示在这里

如果需要在每个实例上序列化静态成员(或const),则可以使用私有实例级访问器作为变通方法:

 [JsonObject(MemberSerialization.OptIn)] public class Test { [JsonProperty] public int x = 1; // static member we want serialized with each instance public static int y = 2; // private accessor to allow Json.net to serialize the static member [JsonProperty("y")] private int y1 { get { return y; } } } 

如果您还需要反序列化到此类,此方法将阻止Json.Net覆盖静态成员,同时仍允许您自己的代码在需要时修改它。