使用带注释的属性名反序列化JSON,并使用原始属性名进行序列化(忽略注释)

本文关键字:注释 属性 序列化 反序列化 JSON 原始 | 更新日期: 2023-09-27 18:17:00

我从外部服务接收JSON,并且说JSON的字段名可能与c#命名规则不兼容。例如

"$" : {//object definition here} 

我不能用一个'$'来命名我的类。我使用System.Runtime.Serialization数据注释来指定一个字段,从中反序列化这个奇怪命名的对象:

 [DataMember(Name = "$")]
 public Item Info { get; set; }

反序列化工作,但现在我想格式化这一点,使它不会被序列化回"$" : {//object definition here}再次。是否有一种方法可以指定一个序列化规则,说这个字段需要用属性名Info序列化,同时仍然从名为$的成员反序列化?我希望我的服务的用户看到的是:

"Info" : {//object definition here} 

使用带注释的属性名反序列化JSON,并使用原始属性名进行序列化(忽略注释)

这样做的一种方法是使用一个自定义的IContractResolver,它基本上告诉Json。Net以忽略属性名注释。在反序列化方面,您允许Json。网络正常工作,因此使用注释。在序列化时,将解析器添加到序列化器设置中,从而生成Json。. Net使用你的类属性名,而不是带注释的名称。

以下是解析器所需的代码:
class OriginalNameContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        // Get the JsonProperties (with annotated names) from the base class
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
        // For each property, replace the annotated name with the real name
        foreach (JsonProperty prop in list)
        {
            prop.PropertyName = prop.UnderlyingName;
        }
        return list;
    }
}

下面是一个演示它是如何工作的:

class Program
{
    static void Main(string[] args)
    {
        string json = @"{ ""$"" : { ""$moniker"" : ""blob sprocket"" } }";
        Foo foo = JsonConvert.DeserializeObject<Foo>(json);
        Console.WriteLine("name from JSON = " + foo.Info.Name);
        Console.WriteLine();
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.ContractResolver = new OriginalNameContractResolver();
        settings.Formatting = Formatting.Indented;
        json = JsonConvert.SerializeObject(foo, settings);
        Console.WriteLine(json);
    }
}
class Foo
{
    [JsonProperty("$")]
    public Item Info { get; set; }
}
class Item
{
    [JsonProperty("$moniker")]
    public string Name { get; set; }
}
输出:

name from JSON = blob sprocket
{
  "Info": {
    "Name": "blob sprocket"
  }
}