如何使用不一致的架构反序列化JSON

时间:2017-12-09 16:36:14

标签: c# json json.net

JavaScript / PHP退伍军人,.NET新手在这里。

我正在尝试使用Json.NET将从API调用返回的JSON数据反序列化为某些类实例。

当JSON模式一致并匹配我的类时,它适用于大多数API调用。但是,我有一些JSON对象返回如下:

"searchresult":{ "summary":{
"page":"1 of 451", "relevancy":"100% - 99%", "count":25, "query":"some search query" }, "0":{ "relevance":100, "id":343, }, "1":{ "relevance":99, "id":434, }, "2":{ ... } },

处理不一致架构的最佳方法是什么,比如“searchresult”?

我创建了一个“SearchResult”,它有一个“Summary”属性,但是我不知道如何映射剩余的项目。

1 个答案:

答案 0 :(得分:2)

为了给你强大的输入,如果模式总是带有:

  • 摘要
  • 不断变化的"相关数"

您可以将JsonConverter类反序列化为名为Summary的类,以及" Relevances"的列表。像这样:

<强>执行:

string json = @"{
    ""searchresult"":{ 
        ""summary"":{

            ""page"":""1 of 451"", 
            ""relevancy"":""100% - 99%"", 
            ""count"":25, 
            ""query"":""some search query"" 
        }, 
        ""0"":{ 
            ""relevance"":100, 
            ""id"":343, 
        }, 
        ""1"":{ 
            ""relevance"":99, 
            ""id"":434, 
        }
    }
}";

var searchResult = JsonConvert.DeserializeObject<SearchResult>(json);

<强>的ViewModels

[JsonConverter(typeof(Converter))]
class SearchResult
{
    public Summary Summary { get; set; }
    public List<RelevanceWrapper> Relevances { get; set; }
}

class Summary
{
    public string Page { get; set; }
    public string Relevancy { get; set; }
    public int Count { get; set; }
    public string Query { get; set; }
}

class RelevanceWrapper
{
    public int Id { get; set; }
    public int Relevance { get; set; }
}

<强> JsonConverter

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);

        var searchResultToken = jObject.GetValue("searchresult");

        var searchResult = new SearchResult()
        {
            Relevances = new List<RelevanceWrapper>()
        };

        foreach (JProperty prop in searchResultToken)
        {
            if (prop.Name == "summary")
            {
                searchResult.Summary = prop.Value.ToObject<Summary>();
            }
            else
            {
                searchResult.Relevances.Add(prop.Value.ToObject<RelevanceWrapper>());
            }
        }

        return searchResult;
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }
}

在ReadJson中有更多的方法可以做到这一点,以及使用Json.Net进行反序列化的其他方法,但我发现这种方式可读性足以理解正在发生的事情。