Json返回列表中的列表

时间:2011-07-19 12:44:35

标签: c# json datacontractserializer

我是使用JSON的新手,我正在努力在列表中专门返回一个列表。我得到以下JSON:

{
    "parameters": {
        "tbdb": "trudon",
        "min_prefix_length": "2",
        "service": "prefix",
        "template": "service.json",
        "term_prefix": "plu"},
    "termHints": [
        {
            "name": "Plumbers & Sanitary Engineers",
            "id":"209654",
            "values": {
                "value":"Plumbers & Sanitary Engineers",
                "pre_em":"",
                "em":"Plu",
                "post_em":"mbers & Sanitary Engineers",
                "nature":"PT",
                "id":"209654"
            }
        },
    ],
    "facets": [
        {
            "id":"209654",
            "name":"Plumbers & Sanitary Engineers"
        }
    ],
    "total":1
}

我使用JSON DataContractJsonSerializer 对此进行了解密,它看起来如下所示:

编辑:在这里做了carlosfigueira建议的更改

    [DataContract]
    public class AutoCompleteResponse
    {
        [DataMember(Name = "parameters")]
        public Parameter Parameters { get; set; }
        [DataMember(Name = "termHints")]
        public List<termHints> hints { get; set; }
        [DataMember(Name = "total")]
        public string Total { get; set; }
    }
    [DataContract]
    public class Parameter
    {
        [DataMember(Name = "tbdb")]
        public string tbdb { get; set; }
        [DataMember(Name = "min_prefix_length")]
        public string min_prefix_length { get; set; }
        [DataMember(Name = "service")]
        public string service { get; set; }
        [DataMember(Name = "template")]
        public string template { get; set; }
        [DataMember(Name = "term_prefix")]
        public string term_prefrix { get; set; }
    }
    [DataContract]
    public class termHints
    {
        [DataMember(Name = "name")]
        public string Name { get; set; }
        [DataMember(Name = "id")]
        public string id { get; set; }
        [DataMember(Name = "values")]
        public values Values { get; set; }
        [DataMember(Name = "facets")]
        public facets Facets { get; set; }

    }
    [DataContract]
    public class values
    {
        [DataMember(Name = "value")]
        public string value_name { get; set; }
        [DataMember(Name = "pre_em")]
        public string pre_em { get; set; }
        [DataMember(Name = "em")]
        public string em { get; set; }
        [DataMember(Name = "post_em")]
        public string post_em { get; set; }
        [DataMember(Name = "nature")]
        public string nature { get; set; }
        [DataMember(Name = "id")]
        public string value_id { get; set; }
    }
    [DataContract]
    public class facets
    {
        [DataMember(Name = "id")]
        public string facet_id { get; set; }
        [DataMember (Name = "name")]
        public string facet_name {get; set; }
    }

我的序列化如下所示:

    WebClient w = new WebClient();
    w.DownloadStringCompleted += (a, b) =>
    {
        // Check for errors
        if (b == null) { return; }
        if (b.Error != null) { return; }
        if (string.IsNullOrEmpty(b.Result)) { return; }

        // Desearealize from JSON to .NET objects
        Byte[] bytes = Encoding.Unicode.GetBytes(b.Result);
        MemoryStream memoryStream = new MemoryStream(bytes);
        DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(AutoCompleteResponse));
        AutoCompleteResponse autocompleteSearchResponse = dataContractJsonSerializer.ReadObject(memoryStream) as AutoCompleteResponse;
        memoryStream.Close();

        // Raise Event
        this.OnSearchCompleted(
            new WhatEventArgs()
            {
                response = autocompleteSearchResponse
            }
        );
    };
    w.DownloadStringAsync(builder.Uri);

我创建的回报如下所示:

    public class WhatEventArgs : EventArgs
    {
        public AutoCompleteResponse response { get; set; }
    }

*编辑:添加用于获取数据的代码,这有用...这就是我从值中获取数据的方式,也许我做错了但是我没有得到任何数据(它是空的)我不知道我做错了什么*

    protected void cmdSearch_Click(object sender, EventArgs e)
    {
        AutocompleteWhat search = new AutocompleteWhat()
        {
            Num = 2
        };
        search.SearchCompleted += (a, b) =>
        {
            List<values> _value = new List<values>();
            foreach (termHints item in b.response.hints)
            {
                _value.Add(item.Values);
            }
            if (_value.Count > 0)
            {
                dgvResults.DataSource = _value;
            }
            else
            {
                dgvResults.DataSource = null;
            }
            dgvResults.DataBind();
        };
        search.Search("plu");
    }

我现在需要从提示中获取实际值,但是从值返回的数据是空的。我不明白为什么,请看看你能看到我看不到的东西。

编辑修正了Json,错过了“facets”的结束时间

1 个答案:

答案 0 :(得分:0)

要使DataContractJsonSerializer正常工作,您需要拥有一个类型系统,其架构与JSON相匹配。 “values”字段不是列表(或数组) - 它是另一个JSON对象,因此您不需要将其声明为List<Value> - 它只是一个Value对象。

此外,termHints类的DataMember Name属性被设置为各自成员的'Values'和'Facets',但在json中,名称是小写的,因此您也需要更改它( DataMember(Name =“values”)和DataMember(Name =“facets”)。

使用代码更新

我在代码/ JSON中看到的另一个问题是,在JSON文档中,facetstermHints的兄弟,但在您拥有的数据协定中,facet是提示的子代。所以其中一个需要改变。下面是两个版本的代码,只需选择一个:)

public class StackOverflow_6747339
{
    class FacetsAsSiblingOfHints
    {
        [DataContract]
        public class AutoCompleteResponse
        {
            [DataMember(Name = "parameters")]
            public Parameter Parameters { get; set; }
            [DataMember(Name = "termHints")]
            public List<TermHints> Hints { get; set; }
            [DataMember(Name = "facets")]
            public List<Facets> Facets { get; set; }
            [DataMember(Name = "total")]
            public string Total { get; set; }

            public override string ToString()
            {
                return string.Format("AutoCompleteResponse[Parameters={0},hints={1},facets={2},total={3}]",
                    Parameters, ListToString(Hints), ListToString(Facets), Total);
            }
        }
        [DataContract]
        public class Parameter
        {
            [DataMember(Name = "tbdb")]
            public string tbdb { get; set; }
            [DataMember(Name = "min_prefix_length")]
            public string min_prefix_length { get; set; }
            [DataMember(Name = "service")]
            public string service { get; set; }
            [DataMember(Name = "template")]
            public string template { get; set; }
            [DataMember(Name = "term_prefix")]
            public string term_prefrix { get; set; }

            public override string ToString()
            {
                return string.Format("Parameter[tbdb={0},min_prefix_length={1},service={2},template={3},term_prefix={4}]",
                    tbdb, min_prefix_length, service, template, term_prefrix);
            }
        }
        [DataContract]
        public class TermHints
        {
            [DataMember(Name = "name")]
            public string Name { get; set; }
            [DataMember(Name = "id")]
            public string Id { get; set; }
            [DataMember(Name = "values")]
            public Values Values { get; set; }

            public override string ToString()
            {
                return string.Format("TermHints[Name={0},Id={1},Values={2}]", Name, Id, Values);
            }
        }
        [DataContract]
        public class Values
        {
            [DataMember(Name = "value")]
            public string value_name { get; set; }
            [DataMember(Name = "pre_em")]
            public string pre_em { get; set; }
            [DataMember(Name = "em")]
            public string em { get; set; }
            [DataMember(Name = "post_em")]
            public string post_em { get; set; }
            [DataMember(Name = "nature")]
            public string nature { get; set; }
            [DataMember(Name = "id")]
            public string value_id { get; set; }

            public override string ToString()
            {
                return string.Format("Values[value_name={0},pre_em={1},em={2},post_em={3},nature={4},value_id={5}]",
                    value_name, pre_em, em, post_em, nature, value_id);
            }
        }
        [DataContract]
        public class Facets
        {
            [DataMember(Name = "id")]
            public string facet_id { get; set; }
            [DataMember(Name = "name")]
            public string facet_name { get; set; }

            public override string ToString()
            {
                return string.Format("Facets[facet_id={0},facet_name={1}]", facet_id, facet_name);
            }
        }

        const string json = @"{
""parameters"": {
    ""tbdb"": ""trudon"",
    ""min_prefix_length"": ""2"",
    ""service"": ""prefix"",
    ""template"": ""service.json"",
    ""term_prefix"": ""plu""},
""termHints"": [
    {
        ""name"": ""Plumbers & Sanitary Engineers"",
        ""id"":""209654"",
        ""values"": {
            ""value"":""Plumbers & Sanitary Engineers"",
            ""pre_em"":"""",
            ""em"":""Plu"",
            ""post_em"":""mbers & Sanitary Engineers"",
            ""nature"":""PT"",
            ""id"":""209654""
        }
    },
],
""facets"": [
    {
        ""id"":""209654"",
        ""name"":""Plumbers & Sanitary Engineers""
    }
],
""total"":1
}";

        internal static void Test()
        {
            Console.WriteLine("Facets as siblings of the hints");
            DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(AutoCompleteResponse));
            MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            AutoCompleteResponse obj = (AutoCompleteResponse)dcjs.ReadObject(ms);
            ms.Close();
            Console.WriteLine(obj);
            Console.WriteLine();
        }
    }

    class FacetsInsideHints
    {
        [DataContract]
        public class AutoCompleteResponse
        {
            [DataMember(Name = "parameters")]
            public Parameter Parameters { get; set; }
            [DataMember(Name = "termHints")]
            public List<TermHints> Hints { get; set; }
            [DataMember(Name = "total")]
            public string Total { get; set; }

            public override string ToString()
            {
                return string.Format("AutoCompleteResponse[Parameters={0},hints={1},total={2}]",
                    Parameters, ListToString(Hints), Total);
            }
        }
        [DataContract]
        public class Parameter
        {
            [DataMember(Name = "tbdb")]
            public string tbdb { get; set; }
            [DataMember(Name = "min_prefix_length")]
            public string min_prefix_length { get; set; }
            [DataMember(Name = "service")]
            public string service { get; set; }
            [DataMember(Name = "template")]
            public string template { get; set; }
            [DataMember(Name = "term_prefix")]
            public string term_prefrix { get; set; }

            public override string ToString()
            {
                return string.Format("Parameter[tbdb={0},min_prefix_length={1},service={2},template={3},term_prefix={4}]",
                    tbdb, min_prefix_length, service, template, term_prefrix);
            }
        }
        [DataContract]
        public class TermHints
        {
            [DataMember(Name = "name")]
            public string Name { get; set; }
            [DataMember(Name = "id")]
            public string Id { get; set; }
            [DataMember(Name = "values")]
            public Values Values { get; set; }
            [DataMember(Name = "facets")]
            public List<Facets> Facets { get; set; }

            public override string ToString()
            {
                return string.Format("TermHints[Name={0},Id={1},Values={2},Facets={3}]", Name, Id, Values, ListToString(Facets));
            }
        }
        [DataContract]
        public class Values
        {
            [DataMember(Name = "value")]
            public string value_name { get; set; }
            [DataMember(Name = "pre_em")]
            public string pre_em { get; set; }
            [DataMember(Name = "em")]
            public string em { get; set; }
            [DataMember(Name = "post_em")]
            public string post_em { get; set; }
            [DataMember(Name = "nature")]
            public string nature { get; set; }
            [DataMember(Name = "id")]
            public string value_id { get; set; }

            public override string ToString()
            {
                return string.Format("Values[value_name={0},pre_em={1},em={2},post_em={3},nature={4},value_id={5}]",
                    value_name, pre_em, em, post_em, nature, value_id);
            }
        }
        [DataContract]
        public class Facets
        {
            [DataMember(Name = "id")]
            public string facet_id { get; set; }
            [DataMember(Name = "name")]
            public string facet_name { get; set; }

            public override string ToString()
            {
                return string.Format("Facets[facet_id={0},facet_name={1}]", facet_id, facet_name);
            }
        }

        const string json = @"{
""parameters"": {
    ""tbdb"": ""trudon"",
    ""min_prefix_length"": ""2"",
    ""service"": ""prefix"",
    ""template"": ""service.json"",
    ""term_prefix"": ""plu""},
""termHints"": [
    {
        ""name"": ""Plumbers & Sanitary Engineers"",
        ""id"":""209654"",
        ""values"": {
            ""value"":""Plumbers & Sanitary Engineers"",
            ""pre_em"":"""",
            ""em"":""Plu"",
            ""post_em"":""mbers & Sanitary Engineers"",
            ""nature"":""PT"",
            ""id"":""209654""
        },
        ""facets"": [
            {
                ""id"":""209654"",
                ""name"":""Plumbers & Sanitary Engineers""
            }
        ]
    },
],
""total"":1
}";

        internal static void Test()
        {
            Console.WriteLine("Facets inside the hints");
            DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(AutoCompleteResponse));
            MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            AutoCompleteResponse obj = (AutoCompleteResponse)dcjs.ReadObject(ms);
            ms.Close();
            Console.WriteLine(obj);
            Console.WriteLine();
        }
    }

    static string ListToString<T>(List<T> list)
    {
        if (list == null)
        {
            return "<<null>>";
        }

        StringBuilder sb = new StringBuilder();
        sb.Append("[");
        for (int i = 0; i < list.Count; i++)
        {
            if (i > 0) sb.Append(",");
            sb.Append(list[i]);
        }

        sb.Append("]");
        return sb.ToString();
    }

    public static void Test()
    {
        FacetsAsSiblingOfHints.Test();
        FacetsInsideHints.Test();
    }
}