views:

103

answers:

2

The answer to just about every single question about using C# with json seems to be "use JSON.NET" but that's not the answer I'm looking for.

the reason I say that is, from everything I've been able to read in the documentation, JSON.NET is basically just a better performing version of the DataContractSerializer built into the .net framework...

Which means if I want to deserialize a JSON string, I have to define the full, strongly-typed class for EVERY request I might have. so if I have a need to get categories, posts, authors, tags, etc, I have to define a new class for every one of these things.

This is fine if I built the client and know exactly what the fields are, but I'm using someone else's api, so I have no idea what the contract is unless I download a sample response string and create the class manually from the JSON string.

Is that the only way it's done? Is there not a way to have it create a kind of hashtable that can be read with json["propertyname"]?

Finally, if I do have to build the classes myself, what happens when the API changes and they don't tell me (as twitter seems to be notorious for doing)? I'm guessing my entire project will break until I go in and update the object properties...

So what exactly is the general workflow when working with JSON? And by general I mean library-agnostic. I want to know how it's done in general, not specifically to a target library...

I hope that made sense, this has been a very confusing area to get into...

thanks!

+3  A: 

It is very hard to be library-agnostic as you request because how you work with json really depends on the library you use. As an example inside JSON.NET there are multiple ways you could work with JSON. There is the method you talk about with direct serialization into objects. That is type safe but will break if the data from your API changes. However, there is also a LINQ-to-JSON that provides a JObject (which behaves fairly similarly to XElement) that provides a way to do JObject["key"] as you requested in your question. If you are really just looking for a flexible way to work with JSON inside C#, then check out JSON.NET's LINQ-to-JSON.

In reality no matter how you do it, if the API changes your code is likely to break. Even if you are just strictly a hashtable-based approach, your code will still be likely to break if the data coming back changes.

Edit

JSON.NET Documentation

Examples

If you check out the examples, the second one should give you a good example of how LINQ-to-JSON works. It allows you to work with it without defining any classes. Everything gets converted to standard framework classes (mostly collections and strings). This avoids the need to maintain classes.

Stephan
thank you for your reply!does json.net have any tools to simplify development of these contracts? some apis have dozens of return objects and it would be a pain to have to write them all, especially if I'm using this to access multiple apis from different providers...
Josh
With the JSON.NET Linq stuff you don't have to define the return objects explicitly. You work with the JSON through arrays, largely like you would in JavaScript. Updated answer with some links.
Stephan
ahh the Examples link looks like exactly what I'm looking for, thanks again!one last question then, if I do decide I want to work with strongly-typed objects after all, am I limited to deriving my classes manually by mapping from an example returned JSON string?that is, would I have to issue a request, get the return JSON string, open it in notepad and create the class myself from the fields I see in the string?or is there any kind of tool to help automate this?thanks yet again!
Josh
I would guess you probably need to create them manually. I don't know of an automated tool that exists, but it wouldn't be incredibly difficult to write a tool that reads a JSON string and outputs code. You could probably use the LINQ-to-JSON in combination with the CodeDom namespace to iterate over the returned object and generate a C# class to represent it.
Stephan
A: 

I've been a Perl developer for over a decade, and I've just recently started to work in C#. I'm surprised by how much I like it (I don't like Java at all) but one of the most difficult cognitive switches is going from "Everything can be treated as a string and the language takes care of conversions" to "Pre-define your types." In this case string-thinking might be an advantage, because it's what you need to do for the kind of API you're asking for.

You need to write a JSON parser that understands the syntax, which is fairly simple: comma-separated lists, key/value pairs, {} for hashes/objects, [] for arrays, and quoting/escaping constructs. You'll want to create a Hashtable to start because the top-level entity in JSON is always an object, then scan the JSON string character-by-character. Pull out key/value pairs; if the value starts with { then add it as a new Hashtable, if it starts with [ add it as a new ArrayList, otherwise add it as a string. If you get { or [ you'll need to recursively descend to add the child data elements.

If .NET has a good recursive descent parser, you could probably use that to make the job simpler or more robust, but JSON is simple enough to make this a good and reasonably completable exercise.

DougWebb
As Stephen notes in his response, this approach is fine so long as you're not dependent on the particular keys/values in use. For example if you were just displaying the JSON data structure you don't need a priori knowledge of the keys. However, if your application is going to have key names hardcoded, you're tied to the service's API and you can break if the API changes.That said, the string-based approach is more robust than a typical strongly-typed system. Strongly-typed interfaces like this typically can't handle any change at all, while a string-based system will be ok with eg: new keys
DougWebb