2

For my ASP.Net application I need to use a HTTP REST API that returns a JSON object. Here's how the JSON looks:

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

I could use the DataContractJsonSerializer Class and have custom Classes defined. However, am not sure how keys like "$" would get converted to in .Net.

Any suggestions?

3
  • 2
    Whoever popularised $ as a variable name should be hung out to dry. Commented Sep 14, 2010 at 13:48
  • @spender You mean John Resig...? Commented Sep 15, 2010 at 13:42
  • I'd be stupid to mention names. Look what happened to Paul Chambers after his Twitter joke. Commented Sep 15, 2010 at 13:46

3 Answers 3

3

This looks like it does something like what you want, with 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);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

JSON.Net seems cool. Can you throw some light on how I can use the properties from the reparsed object? Am getting some errors when I do reparsed.Item("response") Note that I populated reparsed object from my JSON string
@Vidhyashankar: Use the indexer: reparsed["response"]
2

I see no problem to use standard DataContractJsonSerializer to read the data with "$" field. Much more problem I see that you data is not yes in JSON format. If you mean that the data from the question is only an object which will be serialized then the serialized JSON data will be looks like following

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

or

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

All properties will be double quoted and slash will be escaped (see http://www.json.org/). You can verify on the JSON Validator, that the data are correct JSON data.

To read the data (deserialize) or write (serialize) with respect of DataContractJsonSerializer you can without any problem. Like I mention before you should only use Name properties of DataMember attribute:

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);
            }
        }
    }
}

The program produce following output

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}}]}

2 Comments

Am not able to get this working for my JSON where 'message' is repeated multiple times. Otherwise, this is fine.
@Vidhyashankar: I am sure, that you made a simple error in using multiple 'message' items. Look at the modified code and the output of the code in my answer. How you could compare it with the old code you need only modify definition of MessageCollection mc and string json.
1

DataContractJsonSerializer has a lot of limitations and I personally haven't had good experiences working with it.

I would suggest JSON .NET or if you're using .NET 4.0, perhaps an IDynamicObjectMetaProvider.

Example of the latter is here, but there are several other simple implementations out there: http://www.charlierobbins.com/articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.