To define a type that will deserialize the given json into a type that mimicks the known structure + some unknown structure, use Json.Net and use this type:
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>();
}
Please know that the "Results" sub-property in the first json will be difficult to handle in this concept, so you should still strive to make a "detection" algorithm that looks at a subset of the properties, and if some specific key properties exists, pick a different and more correct type to deserialize the json into.
For instance, here is a simple such heuristics:
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; }
}
Do note that this deserializes the json twice. There are different ways to handle/avoid that but you will have to decide if this is a valid way forward.