如何使JSON序列化程序忽略模型中的属性并根据属性名称进行反序列化

3
根据特定条件,我需要将JSON字符串反序列化为不同的模型,有时是模型A,有时是模型B。然而,在模型A中,有来自System.Text.Json.Serialization的JsonPropertyName属性,而在类B中,则有来自Newtonsoft.Json的JsonProperty属性。问题是JSON字符串对应于实际属性名称,而不是属性中给出的名称。我希望使JSON序列化器(无论是Newtonsoft还是System.Text)忽略自己的属性。这可行吗?
下面是一个JSON字符串示例:
{
  "PropertyOne" : "some value"
}

以下是一个示例模型:

public class A
{
  [JsonProperty("property_one")]
  public string PropertyOne{ get; set; }
}

public class B
{
  [JsonPropertyName("property_one")]
  public string PropertyOne{ get; set; }
}

PS 我无法更改模型


我假设 Newtonsoft.Json 会忽略 System.Text.Json 的属性,反之亦然,因此当反序列化一个类时,您可能需要使用 Newtonsoft,而在反序列化另一个类时则需要使用 System.Text.Json。 - Zohar Peled
2
听起来需要自定义合同解析器。您可以在此处看到一个相关的示例:https://dev59.com/dmIj5IYBdhLWcg3wHhpX#20639697 - Sergey Kudriavtsev
1个回答

3
正如Sergey Kudriavtsev在评论区中建议的那样,自定义合同解析器对我的用例非常有效。我将为任何遇到类似问题的人留下解决方案。
以下是自定义合同解析器类:
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;

namespace mynamespace
{
  public class DefaultNameContractResolver : DefaultContractResolver
  {
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
      // Let the base class create all the JsonProperties 
      IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

      // Now inspect each property and replace the name with the real property name
      foreach (JsonProperty prop in list)
      {
        prop.PropertyName = prop.UnderlyingName;
      }
      return list;
    }
  }
}

以下是如何使用它的步骤:
string json = "{ \"PropertyOne\" : \"some value\" }";
Type recordType = typeof(A);
Newtonsoft.Json.JsonSerializerSettings settings = new()
{
  ContractResolver = new mynamespace.DefaultNameContractResolver()
};
var myObject = Newtonsoft.Json.JsonConvert.DeserializeObject(json, recordType, settings);

我正在寻找这个的 system.text 版本 :( - Anil P Babu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接