c# - 使用不同的模式反序列化 JSON

标签 c# json json.net

我在 .NET 4.7 中使用 JSON.Net。

在我调用的 API 中,对于同一个调用,我可以随机获得两种错误 json :(。

错误类型 1:

{
   "Code": 0,
   "Msg": ["Some Warning"]
}

错误类型 2:

{
    "Code": 0,
    "Msg": [
          {"Error": 5 },
          {"Error": 6 }
    ]
}

如您所见,Msg 改变了它的结构。我想要一个通用的 POCO 来反序列化,但是当 Msg 发生变化时如何?

JsonConvert.DeserializeObject<MyCommonPoco>(theJson);

最佳答案

您可以 write a custom JsonConverter处理不同的类型。例如,您可以拥有以下 JSON:

{
    "Code": 0,
    "Msg": [
        "A single string",
        { "Message": "An object with a message" },
        { "Message": "An object with a message and a code", "Code": 5 },
        { "Code": 5 }
    ]
}

在此示例中,Msg 数组可以包含原始字符串或复杂对象。该对象可以包含 MessageCode 或两者。

您可以为此选择最常见的数据结构,一种能够表示所有信息的数据结构。这意味着,例如,您必须将该原始字符串包装到一个兼容的对象中。

public class Error
{
    public int Code { get; set; }
    public ErrorMessage[] Msg { get; set; }
}

public class ErrorMessage
{
    public string Message { get; set; }
    public int? Code { get; set; }
}

然后你可以使用自定义

然后,使用自定义 JsonConverter ,你可以解析上面的 JSON:

public class ErrorMessageConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
        => objectType == typeof(ErrorMessage);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // handle the primitive string
        if (reader.TokenType == JsonToken.String)
            return new ErrorMessage { Message = (string)reader.Value };

        // handle a complex object; just assume that it is an `ErrorMessage` here
        else if (reader.TokenType == JsonToken.StartObject)
            return JObject.Load(reader).ToObject<ErrorMessage>();

        throw new NotSupportedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

这将是使用该转换器的一种方式:

// the single quotes are just here to make it more readable; JSON.NET support this
// although it isn’t valid JSON
var json = @"{
    'Code': 0,
    'Msg': [
        'A single string',
        { 'Message': 'An object with a message' },
        { 'Message': 'An object with a message and a code', 'Code': 5 },
        { 'Code': 5 }
    ]
}";

var settings = new JsonSerializerSettings()
settings.Converters.Add(new ErrorMessageConverter());

var result = JsonConvert.DeserializeObject<Error>(json, settings);

Successfully parsed result

关于c# - 使用不同的模式反序列化 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51756145/

相关文章:

json - 读取外部 JSON 文件

c# - 使用 Newtonsoft、dotnet core 2.2 与 dot net core 3.1 对 System.Version 进行序列化和反序列化

c# - newtonsoft.json 库错误

c# - 回发后,我的 JavaScript 函数在 ASP.NET 中不起作用

json - 小写 JSON 中的值

c# - 如何将我的数据库上下文注入(inject)我所有的存储库类

ios - 如何在 UITableview 第一节中显示字典数组第一个值,在 UITableview 第二节中显示剩余值?

c# - 在 ASP.NET Web API 中抑制 JsonMediaTypeFormatter 的 RequiredAttribute 验证

c# - 解决播放WAV文件时出现问题

c# - 如何知道在 ListView 中右键单击了哪个标题列?