在 C# 中解析具有未定义结构的 Json 响应



我正在尝试解析来自我无法控制的 Web API 的对象响应

因此,其中一个响应是这样的:

{
    "BatchID": 25,
    "Results": [{
        "ItemID": 123,
        "ResultMessage": "COMPLETED"
    }, {
        "ItemID": 456,
        "ResultMessage": "COMPLETED"
    }],
    "COMPLETED_COUNT": 2,
    "INPROGRESS_COUNT": 0,
    "FAILED_COUNT": 0
}

使用NewtonSoft Json库很容易解析;但是我也遇到过这种情况:

{
    "3305": "COMPLETE",
    "7305": "COMPLETE",
    "COMPLETED_COUNT": 2,
    "INPROGRESS_COUNT": 0,
    "FAILED_COUNT": 0
}

我不知道我会遇到多少int属性。在此示例中只有两个"3305"和"7305"

我的问题是:有没有办法创建一个可以容纳该响应中每个整数的对象?

感谢您的帮助。

您可能想尝试将从 API 获取的 JSON 转换为 JObject 的实例。它包含带有名称和值的所有属性

要定义一个类型,将给定的 json 反序列化为模仿已知结构 + 一些未知结构的类型,请使用 Json.Net 并使用此类型:

public class Response
{
    [JsonProperty("COMPLETED_COUNT")]
    public int CompletedCount { get; set; }
    [JsonProperty("INPROGRESS_COUNT")]
    public int InProgressCount { get; set; }
    [JsonProperty("FAILED_COUNT")]
    public int FailedCount { get; set; }
    [JsonExtensionData]
    public Dictionary<string, object> ExtraData { get; } = new Dictionary<string, object>();
}

请注意,在这个概念中,第一个 json 中的"结果"子属性将很难处理,因此您仍应努力制作一个"检测"算法来查看属性的子集,如果存在某些特定的键属性,请选择不同的、更正确的类型将 json 反序列化为。

例如,这里有一个简单的启发式方法:

public static ResponseBase Classify(string json)
{
    var response = JsonConvert.DeserializeObject<ResponseBase>(json);
    if (response.ExtraData.ContainsKey("Results"))
        return JsonConvert.DeserializeObject<ResponseWithResults>(json);
    return response;
}
public class ResponseBase
{
    [JsonProperty("COMPLETED_COUNT")]
    public int CompletedCount { get; set; }
    [JsonProperty("INPROGRESS_COUNT")]
    public int InProgressCount { get; set; }
    [JsonProperty("FAILED_COUNT")]
    public int FailedCount { get; set; }
    [JsonExtensionData]
    public Dictionary<string, object> ExtraData { get; } = new Dictionary<string, object>();
}
public class ResponseWithResults : ResponseBase
{
    public int BatchId { get; set; }
    public List<ResponseResult> Results { get; } = new List<ResponseResult>();
}
public class ResponseResult
{
    public int ItemId { get; set; }
    public string ResultMessage { get; set; }
}

请注意,这会反序列化 json 两次。有不同的方法可以处理/避免这种情况,但您必须决定这是否是一种有效的前进方式。

相关内容

  • 没有找到相关文章