如何使用JSON.NET序列化静态或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#静态参考中没有看到任何帮助。我对c#比较陌生,这是一个非常有趣的问题。

如果需要的话,它当然可以序列化静态变量。序列化是通过使用反射api检查对象和类型来完成的,这些api允许你做"任何事情"——没有技术上的原因不能序列化这些值。

然而,有一个逻辑上的理由不支持这个默认值:它没有多大意义。您正在序列化一个实例,并且staticconst成员在逻辑上不是实例的一部分,而是整个类的一部分。 也就是说,你仍然可以序列化static成员,如果它是一个属性:
[JsonProperty]
public static int y { get; set; } // this will be serialized

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

As of Json。NET 6.0.4中,static和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文件中,然后将该文件捆绑到angular应用程序中。你将生成的JS对象附加到$rootScope中,所有的angular代码都可以访问这些常量。

如果需要在每个实例上序列化静态成员(或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。

如果需要,仍然允许自己的代码修改它。

最新更新