【问题标题】:Newtonsoft Json - Deserialize - Custom mapping if property name is same but property type is differentNewtonsoft Json - 反序列化 - 如果属性名称相同但属性类型不同,则自定义映射
【发布时间】:2016-07-01 07:38:08
【问题描述】:

我正在调用 REST API 以获取对象作为 ResponseData。

CustomField CustomFieldObj = JsonConvert.DeserializeObject<CustomField>(ResponseData.ToString());

// 类定义(DataTypeint? 类型)

public class CustomField {
 public int? DataType {get; set;}
}

API 有这样的对象(DataTypestring 类型)

public class ResposeData {
     public string DataType {get; set;}
    }

现在,JsonConvert.DeserializeObject 由于数据类型不同(字符串无法转换为 int)而引发错误。
那么,如何在反序列化时忽略这些具有不同数据类型的属性呢?

【问题讨论】:

  • 发布 JSON 字符串和确切的错误。虽然,如果您尝试将 "someString123" 转换为整数,那么您做错了。如果 API 希望该字段是数字而不是字符串,他们会将其序列化为数字。例如,如果您省略扩展名和国际代码,电话号码可能看起来像 int,但将其视为 int 绝对是一个错误
  • 是的,这正是发生的事情。如何自定义某些特定属性的映射?
  • 我无法更改任何对象类型。所以我必须在反序列化时以某种方式对其进行自定义。我可以为此传递任何参数吗?
  • 没有代码,没有 JSON,没有错误,没有人可以回答。您不能123sd 反序列化为 int。你确定文本可以被解析为整数吗?此外,如果为调用 API 而创建的对象类型错误,您应该修复该错误,而不是试图掩盖它。否则,您必须创建 new 对象来读取输入,过滤掉那些无法解析的对象并将其余对象映射到现有对象
  • 好的,我正在更新问题

标签: c# .net rest serialization json.net


【解决方案1】:

复杂的答案是您可以指定要在反序列化过程中使用的转换器:JsonConverter

基础是,您可以使用JsonConverter 作为基类并覆盖这些属性:

public class KeysJsonConverter : JsonConverter
{
    private readonly Type[] _types;

    public KeysJsonConverter(params Type[] types)
    {
        _types = types;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);

        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
        }
        else
        {
            JObject o = (JObject)t;
            IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();

            o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));

            o.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }
}

这是来自 James Newton-King 的 extract

如果您希望将 JSON 读入对象,那么您将寻求覆盖 ReadJsonCanRead 方法。

如果您希望指定此转换器可以读取 json,请覆盖 CanRead 方法并返回 true。

然后您需要重写ReadJson 方法才能读出这些值。

source code for other converters 将在一定程度上帮助您了解如何实现ReadJson,但请注意您将使用反射。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 1970-01-01
    • 2016-11-01
    相关资源
    最近更新 更多