JSON (JavaScript Object Notation) is the way to handle data on the client these days. It really is the cat’s pajamas. Almost all the client-side widgets or libraries that you’ll be working with will most likely be utilizing JSON, and sending large chunks of data over the wire as JSON as opposed to other bulky forms of data can lead to some dramatic performance increase across any application. I often come across individuals not sure of what JSON is, or how they can use it today, and I wanted to address this issue in a blog post. Of course I also want to take a look at what’s coming in ASP.NET 4.5 because I also want to show you the future of using JSON in our ASP.NET AJAX applications. So grab your whip and your favorite hat, come with me and let’s go exploring into the frontier that is JSON!
I think it will be a good idea to start at the beginning and take a look at what JSON looks like. Although it’s a fairly simple standard to adhere to, knowing how to manually create a JSON object in JavaScript gives a good foundation to later work with generated JSON objects.
So, let’s say I have a Person object which I want to add three fields to; FirstName (string), LastName (string), ReadytoParty (bool) (because we all need to know if we’re ready to party or not! ;)). For a single person object a simple declaration like the following should work.
var
person = {
"FirstName"
:
"Carl"
,
"LastName"
:
"Bergenhem"
,
"ReadyToParty"
:
true
}
Looks easy enough, right? That’s all there really is too it. Only thing to keep in mind is that, for proper notation, make sure that the field names are surrounded by quotes.
What about if we want to have a collection of these objects? Well, the easiest thing to do is really just to declare the entire collection like following:
var
people = [
{
"FirstName"
:
"Carl"
,
"LastName"
:
"Bergenhem"
,
"ReadyToParty"
:
true
},
{
"FirstName"
:
"Ned"
,
"LastName"
:
"Stark"
,
"ReadyToParty"
:
false
},
{
"FirstName"
:
"Ke$ha"
,
"LastName"
:
"Ke$ha"
,
"ReadyToParty"
:
true
}
];
You can probably tell what book I just finished reading, as well as what was currently playing when I wrote this (the last one I might need to stop admitting too….). You might want to argue if Ned Stark is ready to party or not, but I don’t want to get too off-topic here ;) Anyways, as you probably can tell this is just a JavaScript array of our object. All you have to remember is that for every new object make sure you declare the start and end with { } and keep a comma between each new object.
That’s really all there is to it. If I look at the page where I declared these variables as globals I can take a look at the developer tool console to see the following:
As we can see, person is a single object while people contains multiple objects with the fields and values we set for them.
That’s really all there is to the most basic JSON object – which isn’t too difficult at all! Well, it is fun defining all of this in JavaScript but what if you want to work with a .NET entity and not have to translate data into JSON every single time you are working in JavaScript? Well, just continue reading! :) See what I did there? It’s almost like I planned what was to come next!
The easiest way to work with your .NET objects and have them later be delivered as JSON on the client in ASP.NET AJAX today is probably using an AJAX-enabled WCF Web Service, which is what I’m going to focus on here.
So, open up a basic ASP.NET AJAX project (or a Telerik RadControls project, that works too ;)) and right-click on your project and go to Add > New Item… then you can just search for AJAX-enabled, or WCF, and it should pop up. I simply named mine SampleJSONService. If we open up this service we see the following:
namespace
JSONWebApp
{
[ServiceContract(Namespace =
""
)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public
class
SampleJSONService
{
// To use HTTP GET, add [WebGet] attribute. (Default ResponseFormat is WebMessageFormat.Json)
// To create an operation that returns XML,
// add [WebGet(ResponseFormat=WebMessageFormat.Xml)],
// and include the following line in the operation body:
// WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";
[OperationContract]
public
void
DoWork()
{
// Add your operation implementation here
return
;
}
// Add more operations here and mark them with [OperationContract]
}
}
Hmm, that isn’t too exciting right now. The important things to see here is that we have decorated our class (and this comes out-of-the-box when creating this kind of item) with AspNetCompatibilityRequirements. This is needed to ensure that we can use this WCF web service in our ASP.NET AJAX application. Aside from that there’s a lot of stuff that we will remove eventually, although all of the comments do give us some insight as to what we can do.
Let’s start off by creating the same Person object that I set up when I manually defined my JSON up above. This is being defined within the same WCF web service file as above.
[DataContract]
public
class
Person
{
[DataMember]
public
string
FirstName {
get
;
set
; }
[DataMember]
public
string
LastName {
get
;
set
; }
[DataMember]
public
bool
ReadyToParty {
get
;
set
; }
}
You might notice that I have a few decorations here. I won’t go into details here as there are plenty of resources online that go through each, but think of [DataContract] as the agreement between the server and the client about how the object should look, and what fields are going to be available. This is where [DataMember] comes in to play, as it says “this is a field within my object” and it is used together with [DataContract] to ensure that either side doesn’t cheat on each other (it’d be a mess otherwise! ;))
If we want to put this new shiny object to work, and I know that you all do, let’s just remove all of the junk that is in the web service right now. This is essentially everything within the class, but don’t delete the entity we just created! I’ll just paste in everything I have within the class declaration and I’ll explain what we see afterwards.
[OperationContract]
[WebInvoke(Method =
"GET"
, ResponseFormat = WebMessageFormat.Json)]
public
List<Person> GetPeople()
{
List<Person> myPeople =
new
List<Person>();
myPeople.Add(
new
Person { FirstName =
"Carl"
, LastName =
"Bergenhem"
, ReadyToParty =
true
});
myPeople.Add(
new
Person { FirstName =
"Ned"
, LastName =
"Stark"
, ReadyToParty =
false
});
myPeople.Add(
new
Person { FirstName =
"Ke$ha"
, LastName =
"Ke$ha"
, ReadyToParty =
true
});
return
myPeople;
}
[DataContract]
public
class
Person
{
[DataMember]
public
string
FirstName {
get
;
set
; }
[DataMember]
public
string
LastName {
get
;
set
; }
[DataMember]
public
bool
ReadyToParty {
get
;
set
; }
}
It’s a pretty simple function called GetPeople() that I use to create a new List of the type Person, which I just add the same entities that I had in my peoples variable above. Nothing strange there. What is out of the ordinary are, again, the decorations. [OperationContract] is basically the same as [DataContract] but for functions, and WebInvoke allows us to set up what happens when either a POST or a GET request tries to access this method. Right now I set it up to be GET, and then the very important part is my ResponseFormat parameter. I set this to WebMessageFormat.Json, to ensure that we will get a JSON representation of my collection. We could’ve also done XML and some other formats, but this post is all about JSON!
To see what this looks like in your browser just right-click on your .svc file and select View in Browser. Once the URL has finished loading just add “/GetPeople” to actually call the function we just made. You should see the following text on your page:
{
"d"
:[{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Carl"
,
"LastName"
:
"Bergenhem"
,
"ReadyToParty"
:
true
},{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Ned"
,
"LastName"
:
"Stark"
,
"ReadyToParty"
:
false
},{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Ke$ha"
,
"LastName"
:
"Ke$ha"
,
"ReadyToParty"
:
true
}]}
That looks like JSON to me! However, it’s a bit rough to read so let’s make it a little more readable:
{
"d"
: [
{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Carl"
,
"LastName"
:
"Bergenhem"
,
"ReadyToParty"
:
true
},
{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Ned"
,
"LastName"
:
"Stark"
,
"ReadyToParty"
:
false
},
{
"__type"
:
"SampleJSONService.Person:#JSONWebApp"
,
"FirstName"
:
"Ke$ha"
,
"LastName"
:
"Ke$ha"
,
"ReadyToParty"
:
true
}
]
}
Now if you’re looking at this and saying “woah now, there’s a bunch of fields that we didn’t add!” you’re correct. By default what you see here is the JSON that is being created by our WCF web service. What you see here can be seen as JSON with a .NET flare. We have the type that we’re dealing with for each one of my JSON objects (even tells me the name of my namespace and application), and everything is wrapped in this “d” object, which is placed there to help with cross site scripting items. However, this isn’t the JSON we’re looking for, so let’s go ahead and tweak a few things. First, let’s change the decorations of my GetPeople() function:
[OperationContract]
[WebInvoke(Method =
"GET"
, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
public
List<Person> GetPeople()
{
List<Person> myPeople =
new
List<Person>();
myPeople.Add(
new
Person { FirstName =
"Carl"
, LastName =
"Bergenhem"
, ReadyToParty =
true
});
myPeople.Add(
new
Person { FirstName =
"Ned"
, LastName =
"Stark"
, ReadyToParty =
false
});
myPeople.Add(
new
Person { FirstName =
"Ke$ha"
, LastName =
"Ke$ha"
, ReadyToParty =
true
});
return
myPeople;
}
What I’m adding here is just the BodyStyle parameter, which is set to WebMessageBodyStyle.Bare. Then there is one thing I need to change in my web.config. Within my <system.serviceModel> tags there is a section called behaviors, which contains the code we need to change. Take a look at this sample from my web.config:
<
system.serviceModel
>
<
behaviors
>
<
endpointBehaviors
>
<
behavior
name
=
"JSONWebApp.SampleJSONServiceAspNetAjaxBehavior"
>
<
enableWebScript
/>
</
behavior
>
</
endpointBehaviors
>
</
behaviors
>
<
serviceHostingEnvironment
aspNetCompatibilityEnabled
=
"true"
multipleSiteBindingsEnabled
=
"true"
/>
<
services
>
<
service
name
=
"JSONWebApp.SampleJSONService"
>
<
endpoint
address
=
""
behaviorConfiguration
=
"JSONWebApp.SampleJSONServiceAspNetAjaxBehavior"
binding
=
"webHttpBinding"
contract
=
"JSONWebApp.SampleJSONService"
/>
</
service
>
</
services
>
</
system.serviceModel
>
See where it says <enableWebScript /> all by its lonesome under endpointBehaviors? Well, let’s change that to webHttp:
<
system.serviceModel
>
<
behaviors
>
<
endpointBehaviors
>
<
behavior
name
=
"JSONWebApp.SampleJSONServiceAspNetAjaxBehavior"
>
<
webHttp
/>
</
behavior
>
</
endpointBehaviors
>
</
behaviors
>
<
serviceHostingEnvironment
aspNetCompatibilityEnabled
=
"true"
multipleSiteBindingsEnabled
=
"true"
/>
<
services
>
<
service
name
=
"JSONWebApp.SampleJSONService"
>
<
endpoint
address
=
""
behaviorConfiguration
=
"JSONWebApp.SampleJSONServiceAspNetAjaxBehavior"
binding
=
"webHttpBinding"
contract
=
"JSONWebApp.SampleJSONService"
/>
</
service
>
</
services
>
</
system.serviceModel
>
You might be asking yourself why. Well, enableWebScript is a subclass of webHttp that is built specifically for ASP.NET AJAX functionality and is a little bit constraining if you want to deal with JSON in the fashion we want to work with it in. This is one of the reasons we had all of the added structure to our JSON response earlier, enableWebScript and the default behavior of the AJAX-enabled WCF web service is setting us up to use ASP.NET AJAX-specific implementations. If we set this to webHttp this opens up the doors for us to define how we want our JSON to be served, and also gives us more freedom (which, I heard, costs a buck o-five so we’re essentially making money here ;)).
Side-note: If we do not change this in the web.config we will be greeted by this ugly error:
The body style 'Bare' is not supported by 'WebScriptEnablingBehavior'. Change the body style to be 'WrappedRequest'.
With all of that set, let’s navigate back to our web service as see what kind of response we get.
[
{
"FirstName"
:
"Carl"
,
"LastName"
:
"Bergenhem"
,
"ReadyToParty"
:
true
},
{
"FirstName"
:
"Ned"
,
"LastName"
:
"Stark"
,
"ReadyToParty"
:
false
},
{
"FirstName"
:
"Ke$ha"
,
"LastName"
:
"Ke$ha"
,
"ReadyToParty"
:
true
}
]
Success! We now have the same JSON response that we originally crafted by hand in JavaScript.
Once we’ve set up the web service that we need to communicate with it’s pretty easy to get this data over to the client actually. If we’re using jQuery (which we should all be doing in this day and age!) we can set up .ajax() call in a jiff by just looking at the jQuery.ajax() documentation:
<script type=
"text/javascript"
>
$(document).ready(
function
() {
var
url =
"http://localhost:33716/SampleJSONService.svc/GetPeople"
;
$.ajax({
url: url,
type:
"GET"
,
success:
function
(data) {
var
returnedData = data;
console.log(
"Ajax call succeeded! :D"
);
console.log(returnedData);
},
error:
function
(xhr) {
console.log(
"Ajax call failed :'("
);
console.log(xhr);
}
});
});
</script>
Starting off I’m defining the URL of my web service to a variable called url which for this example is project-dependent and you will have another URL for your web service. This will either come from your project (like I have here), or if you have a separate project hosting the service you would feed that URL here, or if you’re calling to one that’s exposed online that would work too (although depending on the service you might need to add some fields).
To set up the actual ajax call I just provide my URL, set the type to GET as I want to execute this in a GET request, and then define success and failure functions. Since I’ll be checking the result in my Developer Tools (in my case, Google Chrome) I just use some console.log() calls to see if I succeed or not.
When I open up my web page and go to my console I see the following:
So the first console.log call gives what happened away, but that just means that we hit success – what if we still didn’t get the data? Well, do you see the [Object , Object , Object] line? That’s actually the log call of my returned data. So, if we expand each of the Objects we see:
That is indeed my data! Fantastic, we now know how to go from our .NET objects on the server to JSON objects on the client! We kind of get the best of both worlds here now, where we can define and work with our objects in .NET and just pass those to the client and have them automagically become JSON objects.
You might be thinking that there’s no way this will be any easier. However, in ASP.NET 4.5 it actually does. I know, it’s so exciting you’re literally jumping out of your chair and scrolling furiously to the next section, so I’ll shut up for now.
Missed me yet? ;)
The previous approach was the “old” way of handling things. I put old in quotes because it’s still a perfectly valid approach, but we’re always interested in the latest and greatest –right? You should be cheering “YES!”, “Huzzah!” and “I love new stuff!” right now. I’ll just assume you did, that’s OK right? :)
With ASP.NET 4.5 we have a new way of approaching all of this thanks to WebAPI. We actually already have a couple of blog posts relating to this topic, written by my colleague Josh Holt, of which you can find the first one here, and the second one (detailing CRUD operations) right here.
The first one actually goes over how to use WebAPI to get the data over to the client as JSON, so I won’t cover that in this post. I do recommend that you read through that just to get some context though.
What I do want to cover is something that is being introduced with WebAPI; System.Json. This library actually existed in Silverlight earlier, and while I haven’t had a chance to see how it works in Silverlight I have accidentally stumbled upon it and said “huh, what’s that doing here?” I did also check the SL documentation to make sure I wasn’t crazy and making things up ;)
To get access to this brand new awesomeness the easiest thing to do is open up your NuGet package explorer and type in System.Json in the search area. I was a rebel and searched only for Json, so you see a few other libraries out there, but System.Json is the official Microsoft library that we want to use here.
Once you’ve installed this we have a lovely little new assembly sitting in our references folder called System.Json. Once that’s in there we’re good to go!
Anyways, with the introduction of System.Json we get access to the following objects:
Follow me dear reader, and we’ll investigate each of these objects.
As I mentioned above, JsonObject allows us to define objects that we can work with that specifically are made to represent JSON objects. Why is that interesting when we have the ability to create our own entities and just have it translated? Well, the coolest thing to me is the fact that it’s all dynamic. That’s right it’s not just a static object that you define initially and leave it, you can now dynamically set the fields of your object. Additionally everything you define will be a JSON object from the start, which allows you to work with more than just a WCF web service in terms of sending data to the client.
To see what this looks like you can just go to the code-behind of any of your web pages, and put this in the page load (just as an example, I don’t condone bad habits in ASP.NET AJAX!):
dynamic person =
new
JsonObject();
person.FirstName =
"Carl"
;
person.LastName =
"Bergenhem"
;
person.ReadyToParty =
true
;
Now if you put a break point at the line after this (for me it was just the end of the Page_Load event handler) and start the project you will see the following when going back and debugging.
That looks just like the JSON we’ve defined multiple times throughout this post. Awesome! Additionally, this was just as easy as working with it in JavaScript, we just happen to be on the server using C#
A single object isn’t enough, what about a collection? Well this is where JsonArray comes in to play. To recreate our people collection from the first part of this post we just need to add a little bit of extra code, and of course create some new JsonObjects.
dynamic people =
new
JsonArray();
dynamic person =
new
JsonObject();
person.FirstName =
"Carl"
;
person.LastName =
"Bergenhem"
;
person.ReadyToParty =
true
;
people.Add(person);
person =
new
JsonObject();
person.FirstName =
"Ned"
;
person.LastName =
"Stark"
;
person.ReadyToParty =
false
;
people.Add(person);
person =
new
JsonObject();
person.FirstName =
"Ke$ha"
;
person.LastName =
"Ke$ha"
;
person.ReadyToParty =
true
;
people.Add(person);
Pretty easy as well. JsonArray has the Add function where we can just pass our JsonObjects. What does this look like when we take a look at the people object while debugging?
There we go! The same data that we’ve been looking for in every time we look back at our JSON at the end of every section so far.
Now I mentioned something about parsing, and this is where JsonValue comes in to play. You can actually take a JSON string and pass it right to JsonValue and it can parse it for us and create these kind of objects for us! Don’t believe me? Well, let’s take the string from the first section representing our people collection and pass that to the Parse() function of JsonValue. The code should look something like this:
string
peopleString = @"[
{
""
FirstName
""
:
""
Carl
""
,
""
LastName
""
:
""
Bergenhem
""
,
""
ReadyToParty
""
:
true
},
{
""
FirstName
""
:
""
Ned
""
,
""
LastName
""
:
""
Stark
""
,
""
ReadyToParty
""
:
false
},
{
""
FirstName
""
:
""
Ke$ha
""
,
""
LastName
""
:
""
Ke$ha
""
,
""
ReadyToParty
""
:
true
}
]";
dynamic people = JsonValue.Parse(peopleString);
And debugging to see what we have in the people object we see:
Wow, that’s pretty amazing. While this is a static example where I’ve pre-defined everything just imagine what you can do. Create a JSON object and send it over to the client, work with it and manipulate it in JavaScript, then send it back as JSON and parse that out to an object that you can work within .NET in just a line or two of code! Awesome!
That was quite the journey; I hope you aren’t too exhausted. Put down your exploration gear and take a rest knowing that you’ve gone from the basics of JSON, to what you can do today with JSON, and even took a peek into the future of utilizing this within .NET. There are of course other options out there, but I wanted to get a quick look across the most popular and easy way today, as well as a quick example of what we can look forward to in ASP.NET 4.5.
Carl Bergenhem was the Product Manager for Kendo UI.