【问题标题】:Deserialize JSON using annotated property names and serialize using original property names (ignoring annotations)使用带注释的属性名称反序列化 JSON 并使用原始属性名称进行序列化(忽略注释)
【发布时间】:2014-09-30 18:22:09
【问题描述】:

我从外部服务接收 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.NET 吗?您可以在其中编写自己的转换器,允许您指定它的读取和写入方式。

标签: c# json serialization deserialization


【解决方案1】:

一种方法是使用自定义IContractResolver,它基本上告诉 Json.Net 忽略您的属性名称注释。在反序列化时,您让 Json.Net 正常工作,因此使用注释。在序列化时,您将解析器添加到序列化器设置中,这会导致 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"
  }
}

【讨论】:

    猜你喜欢
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 2016-02-11
    相关资源
    最近更新 更多