【问题标题】:Parse a custom JSON object in .Net?在 .Net 中解析自定义 JSON 对象?
【发布时间】:2010-09-14 13:44:00
【问题描述】:

对于我的 ASP.Net 应用程序,我需要使用返回 JSON 对象的 HTTP REST API。 JSON 的外观如下:

message: [
    {
    type: "message"
    href: "/messages/id/23"
    view_href: /this-is-a-test-message/m-p/23
    id: {
        type: "int"
        $: 23
            }
    },
    { //...
    }
]

我可以使用 DataContractJsonSerializer 类并定义自定义类。但是,我不确定在 .Net 中如何将“$”之类的键转换为。

有什么建议吗?

【问题讨论】:

  • 把$作为变量名推广的人应该被晾干。
  • @spender 你是说 John Resig...?
  • 我会愚蠢地提及名字。看看保罗·钱伯斯在推特上开玩笑后发生了什么。

标签: .net asp.net json


【解决方案1】:

这看起来就像你想要的一样,JSON.NET

using System;
using Newtonsoft.Json.Linq;

class Test
{
    static void Main(string[] args)
    {
        JObject top = new JObject(
            new JProperty("type", "message"),
            new JProperty("href", "/messages/id/23"),
            new JProperty("view_href", "/this-is-a-test-message/m-p/23"),
            new JProperty("id", new JObject(new JProperty("type", "int"),
                                            new JProperty("$", 23))));

        Console.WriteLine(top);

        // Round trip        
        string json = top.ToString();
        JObject reparsed = JObject.Parse(json);
    }
}

【讨论】:

  • JSON.Net 看起来很酷。您能否说明我如何使用重新解析对象的属性?执行 reparsed.Item("response") 时出现一些错误请注意,我从 JSON 字符串中填充了重新解析的对象
  • @Vidhyashankar:使用索引器:reparsed["response"]
【解决方案2】:

我认为使用标准DataContractJsonSerializer 读取带有“$”字段的数据没有问题。更多问题我看到你的数据不是 JSON 格式的。如果您的意思是问题中的数据只是一个将被序列化的对象,那么序列化的 JSON 数据将如下所示

{
    "message": [
        {
            "type": "message",
            "href": "\/messages\/id\/23",
            "view_href": "\/this-is-a-test-message\/m-p\/23",
            "id": {
                "type": "int",
                "$": 23
            }
        }
    ]
}

var json = '{"message":[{"type":"message","href":"\/messages\/id\/23","view_href":"\/this-is-a-test-message\/m-p\/23","id":{"type":"int","$":23}}]}'

所有属性都将被双引号引起来,并且斜杠将被转义(参见http://www.json.org/)。您可以在JSON Validator 上验证数据是否为正确的 JSON 数据。

要读取(反序列化)或写入(序列化)DataContractJsonSerializer 的数据,您可以毫无问题。就像我之前提到的,你应该只使用DataMember 属性的Name 属性:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;
using System.IO;

namespace DataContractJsonSerializer4 {
    [DataContract]
    public class MyId {
        [DataMember (Order = 0)]
        public string type;
        [DataMember (Order = 1, Name="$")]
        public int value;
    }
    [DataContract]
    public class Message {
        [DataMember (Order = 0)]
        public string type { get; set; }
        [DataMember (Order = 1)]
        public string href { get; set; }
        [DataMember (Order = 2)]
        public string view_href { get; set; }
        [DataMember (Order = 3)]
        public MyId id { get; set; }
    }
    [DataContract]
    public class MessageCollection {
        [DataMember]
        public List<Message> message { get; set; }
    }

    class Program {
        static void Main (string[] args) {
            MessageCollection mc = new MessageCollection () {
                message = new List<Message> () {
                    new Message() {
                        type = "message",
                        href = "/messages/id/23",
                        view_href = "/this-is-a-test-message/m-p/23",
                        id = new MyId() { type="int", value=23}
                    },
                    new Message() {
                        type = "message",
                        href = "/messages/id/24",
                        view_href = "/this-is-a-test-message/m-p/24",
                        id = new MyId() { type="int", value=24}
                    }
                }
            };
            string json =
                "{" +
                    "\"message\": [" +
                        "{" +
                            "\"type\": \"message\"," +
                            "\"href\": \"\\/messages\\/id\\/23\"," +
                            "\"view_href\": \"\\/this-is-a-test-message\\/m-p\\/23\"," +
                            "\"id\": {" +
                                "\"type\": \"int\"," +
                                "\"$\": 23" +
                            "}" +
                        "}," +
                        "{" +
                            "\"type\": \"message\"," +
                            "\"href\": \"\\/messages\\/id\\/24\"," +
                            "\"view_href\": \"\\/this-is-a-test-message\\/m-p\\/24\"," +
                            "\"id\": {" +
                                "\"type\": \"int\"," +
                                "\"$\": 24" +
                            "}" +
                        "}" +
                    "]" +
                "}";

            DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (MessageCollection));
            using (MemoryStream ms = new MemoryStream (Encoding.Unicode.GetBytes (json))) {
                MessageCollection obj = ser.ReadObject (ms) as MessageCollection;
                Console.WriteLine ("JSON data can be read. The value of the fist $ field is {0}", obj.message[0].id.value);
                using (MemoryStream ms2 = new MemoryStream ()) {
                    ser.WriteObject (ms2, obj);
                    string serializedJson = Encoding.UTF8.GetString (ms2.GetBuffer (), 0, (int)ms2.Length);
                    Console.WriteLine (serializedJson);
                }
            }
            using (MemoryStream memoryStream = new MemoryStream ()) {
                memoryStream.Position = 0;
                ser.WriteObject (memoryStream, mc);

                memoryStream.Flush ();
                memoryStream.Position = 0;
                StreamReader sr = new StreamReader (memoryStream);
                string str = sr.ReadToEnd ();
                Console.WriteLine ("The result of custom serialization:");
                Console.WriteLine (str);
            }
        }
    }
}

程序产生以下输出

JSON data can be read. The value of the fist $ field is 23
{"message":[{"type":"message","href":"\/messages\/id\/23","view_href":"\/this-is-a-test-message\/m-p\/23","id":{"type":"int","$":23}},{"type":"message","href":"\/messages\/id\/24","view_href":"\/this-is-a-test-message\/m-p\/24","id":{"type":"int","$":24}}]}
The result of custom serialization:
{"message":[{"type":"message","href":"\/messages\/id\/23","view_href":"\/this-is-a-test-message\/m-p\/23","id":{"type":"int","$":23}},{"type":"message","href":"\/messages\/id\/24","view_href":"\/this-is-a-test-message\/m-p\/24","id":{"type":"int","$":24}}]}

【讨论】:

  • 我无法为我的 JSON 工作,其中“消息”重复多次。否则,这很好。
  • @Vidhyashankar:我敢肯定,您在使用多个“消息”项目时犯了一个简单的错误。查看我的答案中的 modified 代码和代码输出。如何将其与旧代码进行比较,您只需修改 MessageCollection mcstring json 的定义。
【解决方案3】:

DataContractJsonSerializer 有很多限制,我个人没有很好的使用它的经验。

我建议使用 JSON .NET,或者如果您使用的是 .NET 4.0,则可能是 IDynamicObjectMetaProvider

后者的示例在这里,但还有其他几个简单的实现: http://www.charlierobbins.com/articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-21
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 2023-01-17
    相关资源
    最近更新 更多