【问题标题】:Is there a way to have JSON.net honor the System.Text.Json JsonPropertyName attribute有没有办法让 JSON.net 尊重 System.Text.Json JsonPropertyName 属性
【发布时间】:2021-02-05 17:02:24
【问题描述】:

我有一个表示反序列化 C# 有效负载的 C# 类型。但它由 System.Text.Json 在一个地方反序列化。在另一个地方,它是 Json.NET。

所以现在,我必须同时使用 [JsonProperty](对于 JSON.NET)和 [JsonPropertyName](对于 System.Text.Json)来赋予属性。

有没有办法告诉 JSON.NET 识别 JsonPropertyName 属性,这样我就不必对每个属性进行两次注释?

【问题讨论】:

  • JsonPropertyAttribute 可以指示很多东西,而不仅仅是属性名称:顺序、所需标志等。因此您可能需要重新实现它的各个方面。如果你只用它来表示属性名,你可以实现自己的自定义Contract Resolver
  • @thepirat000 问题是另一种方式 - OP 希望 JSON.NET 处理 JsonPropertyNameAttribute,它只处理名称。
  • 哦,你是对的,对不起。所以自定义合同解析器应该可以工作。

标签: c# json .net json.net system.text.json


【解决方案1】:

您可以创建custom contract resolver,它将搜索JsonPropertyName 属性并使用其中的值。示例一可能看起来像这样:

public class ContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        if (member.GetCustomAttribute<JsonPropertyNameAttribute>() is {} stj)
        {
            property.PropertyName = stj.Name;
            return property;
        }

        return property;
    }
}

及用法:

class MyClass
{
    [JsonProperty("P1")]
    public int MyProperty { get; set; }
    [JsonPropertyName("P2")]
    public int MyProperty2 { get; set; }
}

var settings = new JsonSerializerSettings
{
    ContractResolver = new ContractResolver()
};  

Console.WriteLine(JsonConvert.SerializeObject(new MyClass(), settings)); // prints {"P1":0,"P2":0}
Console.WriteLine(JsonConvert.DeserializeObject<MyClass>("{'P1':1,'P2':2}", settings).MyProperty2); // prints 2

【讨论】:

  • 谢谢,太好了!在我的情况下,我最终用两者来注释我的对象,因为我将它们传递给其他库并且我无法控制它们正在使用的序列化程序。
猜你喜欢
  • 1970-01-01
  • 2020-02-15
  • 2011-04-15
  • 2011-01-15
  • 2016-10-18
  • 2014-06-07
  • 2011-07-31
  • 2012-01-25
  • 2012-05-10
相关资源
最近更新 更多