Newtonsoft Json 仅针对特定 属性 的序列化

Newtonsoft Json Serialization just for specific property

我有两个类,它们之间存在聚合关系

public class Issue
{
    //---
    //tons of other properties
    //---
    
    [JsonProperty("key")]
    public string Key { get; set; }

    [JsonProperty("fields")]
    public Fields Fields { get; set; }

}

public class Fields
{
     //---
     //tons of other properties
     //---
     
     [JsonProperty("customfield_10202")]
     public object Customfield10202 { get; set; }
}

当我将 json 序列化器与合同解析器一起使用时,得到了这样的 json 结果

{
 "customfield_10202": "value"
}

这里是contact resolver和序列化的操作

string json = JsonConvert.SerializeObject(fields, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new DynamicContractResolver("customfield_10202") });

public class DynamicContractResolver : DefaultContractResolver
{
    private readonly string _propertyName;

    public DynamicContractResolver(string propertyName)
    {
        _propertyName = propertyName;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        
        properties =properties.Where(p => p.PropertyName == _propertyName ? true :false).ToList();

        return properties;
    }
}

但我希望 json 的结果像这样

{
    "fields": {
        "customfield_10202": "value"
    }
}

我可以轻松解决这种情况,但似乎不对。如何在不使用字符串变量

的情况下获取我提到的 json 的结果
string json_data = "{ \"fields\": " + json + "}";

假设您有以下 Issue 实例:

var issue = new Issue
{
    Key = "1",
    Fields = new Fields
    {
        Customfield10202 = "value"
    }
};

为了能够序列化

  • fields 来自 Issue class 和
  • customfield_10202 来自 Fields class

您需要将两个 名称传递给解析器。

因此,与其在 ctor 中接收单个 string,不如预期 string 的集合:

public class DynamicContractResolver : DefaultContractResolver
{
    private readonly string[] _properties;

    public DynamicContractResolver(string[] properties)
    {
        _properties = properties;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
        return properties.Where(p => _properties.Contains(p.PropertyName)).ToList();
    }
}

用法会这样改变:

var properties = new[] {"fields", "customfield_10202"};
string json = JsonConvert.SerializeObject(issue, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new DynamicContractResolver(properties) });

生成的输出将如您所愿:

{
  "fields": {
    "customfield_10202": "value"
  }
}