Json in .NET
I use Json all the time, but I feel like it’s super annoying in .NET. Typically I’d call some web service that returns Json. In .NET it seems like the best thing to is to define a data contract and use the DataContractSerializer:
[DataContract]
public class Person
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
then to deserialize whatever string of Json I got back.
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
public static Person DeserializeToPerson( string jsonString )
{
using( MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes( jsonString ) ) )
{
DataContractJsonSerializer serializer =
new DataContractJsonSerializer( typeof( Person ) );
return ( Person )serializer.ReadObject( ms );
}
}
Feels like a lot of code and I need to define the data contract beforehand which seems a little unnecessary given the dynamic nature of web services and Json. Things like the the memory stream reader and getting bytes off the string are brutal. Why can’t i just pass a string to the JsonDataContractSerializer? Some things seem way more complicated in .NET than they need to be. (cref: Calling REST services in .NET)
What I’d like is something closer to Python.
import simplejson as json
person = json.loads(jsonString)
print person.FirstName
That is pretty easy.
With .NET there are some options like:
System.Json
var data = JsonObject.Load(dataStream);
Console.Writeline(data["FirstName"])
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
This is pretty close to what I want. The problem is having to cast sub items to things like JsonArray and what not. Secondly, System.Json only works in Silverlight so i can’t use in a web project or desktop app.
Next option is one of the Json libraries like Json.Net. Not that I mind using any 3rd party DLLs, I just think parsing Json is fairly common if you are calling a rest web service and it should be in the framework, maybe I’m the only one that uses json all the time instead of XML but I’d rather use Lotus Notes everyday than parse XML and you know I hates the Lotus Notes.
This site has an interesting approach: http://blog.petegoo.com/archive/2009/10/27/using-json.net-to-eval-json-into-a-dynamic-variable-in.aspx
2 problems for me. I still need to reference Json.Net and there is that ridiculous looking code to convert to Expando object. I just don’t feel comfortable dropping that blob in my code.
Ideally Json parsing would be something similar but handled in the framework:
dynamic person = JsonObject.Load(jsonString)
Console.Writeline(person.FirstName)
That makes me happy. No pre-defining a contract and something in the framework that can take a string of Json and return back a dynamic object. There is so much stuff in the .NET framework, why can’t there be useful helpers that do common tasks like this.
I could totally be missing simpler solutions so feel free to chime in if I’m just an idiot and missing something obvious.
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }