JSON Serialization and Deserialization in C# with Extension Method

Starting its 3.5 framework, .Net has already support JSON object serialization from System.Web.Script.Serialization.JavaScriptSerializer namespace.

Please note that the code below is an extension method to add ToJson() method to my object.

public static class JsonExtensionMethod
{
    public static string ToJson(this object o)
    {
        System.Web.Script.Serialization.JavaScriptSerializer jsonSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();

        return jsonSerializer.Serialize(o);
    }

    public static T FromJson<T>(this string s)
    {
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

        return serializer.Deserialize<T>(s);
    }
}

The usage is pretty simple and straight-forward. All we need to do is create JavaScriptSerializer instance and call its Serialize method. The method takes object type as its parameter which mean, you can pass all types that derive from System.Object.

To deserialize it, we use Deserialize method of JavaScriptSerializer class.

According to Scott Gu’s post, System.Web.Script.Serialization.JavaScriptSerializer is obsoleting, but will still be available in few versions to come.

Beside System.Web.Script.Serialization.JavaScriptSerializer, you also can use new System.Runtime.Serialization.DataContractJsonSerializer class

Advertisements

Return JSON Data Type in ASP.NET MVC for Jquery Ajax Call

I have this javascript (jquery) code to call a url, “Home/Weather”, that will return JSON data type.

function GetWeatherCondition()
{
    $.ajax({
        url: "Home/Weather",
        dataType: "json",
        success: function (data) {
            alert(data.avgWindDeg);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert(textStatus + " - " + errorThrown);
        }
    });
}

And this is my Weather controller:

public JsonResult Weather()
{
    string urlWebService = "http://i.wxbug.net/REST/Direct/GetObs.ashx?la=41.7233&lo=44.7928&&ic=1&api_key=xxxx";
    string urlWebServiceResponse = "";

    System.Net.WebClient weatherClient = new System.Net.WebClient();
    urlWebServiceResponse = weatherClient.DownloadString(urlWebService);

    return Json(urlWebServiceResponse, JsonRequestBehavior.AllowGet);
}

As you can see, the Weather controller will return JSON object (JsonResult) and the javacsript code will load it in and display data.avgWindDeg. However, there is a problem when I run my javascript code. Instead of data.avgWindDeg, it returns undefined as you can see below:

The Weather controller is actually returning JSON object if I visit the url. So, what’s wrong here?

For some reason, the controller will need to return a JSON string instead of JSON object (JsonResult) for the jquery ajax call ($.ajax()) to understand. Changing my controller to ContentResult instead of JsonResult works like charm.

public ContentResult Weather()
{
    string urlWebService = "http://i.wxbug.net/REST/Direct/GetObs.ashx?la=41.7233&lo=44.7928&&ic=1&api_key=xxxx";
    string urlWebServiceResponse = "";

    System.Net.WebClient weatherClient = new System.Net.WebClient();
    urlWebServiceResponse = weatherClient.DownloadString(urlWebService);

    return Content(urlWebServiceResponse);
}

Getting Data Across (Pass Values) Between View, Controller and External Source in ASP.NET MVC 2 and MVC 3

Here’s the list of my post related to getting data across / pass values between View, Controller and external source:

  1. with Query String (No Modification to Route Table)
  2. with Parameters
  3. with System.Web.Mvc.FormCollection
  4. with Domain Model and / or View Model
  5. (MVC 2) with JSON + ViewModel
  6. (MVC 3) with JSON + VIewModel
  7. (MVC 3) with JSON + ViewModel (Multiple Objects)

JSON Binding Support to Post Array Object with ViewModel in ASP.NET MVC 3

In JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 3, I explained how to take advantage of JSON Binding Support in ASP.NET MVC 3 to post ViewModel object to the Controller. This post will extend the original post to allow posting of multiple objects.

I will use the same ViewModel as in the original post with the addition of the following object, which basically contains list of Person object:

public class Persons
{
    public List<Person> PersonList { get; set; }
}

The Controller will be pretty much the same as the original post, with the exception of the parameter:

[HttpPost]
public ActionResult SubmitMultiplePostObjectsInJsonWithViewModel(Development.MvcApp.Models.Persons objectsModel)
{
    return View(objectsModel);
}

This will allow the Controller to receive multiple Person objects as Persons ViewModel.

Here’s the JSON object I sent to the Controller:

{ "PersonList": [{ "Firstname": "testFirstname1", "Lastname": "testLastname1", "Email": "testEmail1", "PhoneNumber": "testNumber1" }, { "Firstname": "testFirstname2", "Lastname": "testLastname2", "Email": "testEmail2", "PhoneNumber": "testNumber2"}] }

The request:

The response:

Few important notes:

  1. The ViewModel object’s properties (“PersonList”) must match JSON object’s string.
  2. The ViewModel object’s properties must have “{ get; set; }”.
  3. The request’s Content Type must be “application/json”.

JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 2

JSON Binding Support is only available in ASP.NET MVC 3. However, there is a workaround we can do to make this work in ASP.NET MVC 2.

I will use the same ViewModel in ASP.NET MVC 3 Post.

Here’s the Controller:

public ActionResult SubmitPostObjectInJsonWithViewModel(string objectModel)
{
    System.Web.Script.Serialization.JavaScriptSerializer _jsonDeserializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var _person = _jsonDeserializer.Deserialize(objectModel, new Development.MvcApp.Models.Person().GetType());

    return Json(_person);
}

For simple demonstration purpose, the Controller only returns Json object pass to the Controller.

As mentioned in ASP.NET MVC 3 Post, I use Poster, a Mozilla Firefox add-on to test posting to the Controller.

Here’s the request:

Here’s the response:

Basically, this approach is the same as what I described here. We take string input (which essentially is a JSON string) in our Controller and deserialize it to our ViewModel object.

Few things to note:

  1. The request must NOT be “application/json”. The request is a regular post action request.
  2. Parameter used in Controller must match the request parameter’s name.
  3. System.Web.Script.Serialization.JavaScriptSerializer is obsoleting according to Scott Gu’s post, but will still be available in few .Net versions to come.

JSON Binding Support to Post Action Method with ViewModel in ASP.NET MVC 3

ViewModel object is very good solution for form posting when used within internal application. But, what if your ASP.NET MVC application needs to communicate with outside world? There’s JSON Binding Support in ASP.NET MVC 3.

The best part is, ViewModel object can still be used in this approach.

Controller to process post back:

[HttpPost]
public ActionResult SubmitPostObject(Development.MvcApp.Models.Person objectModel)
{
    return Json(objectModel);
}

The ViewModel:

public class Person
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
}

To test this, I will use Poster, an add-on for Mozilla Firefox.

As you can see, I specify the following Json object to be sent to the Controller:

{ "Firstname": "Alexander", "Lastname": "Witt", "Email": "awitt@gmail.com", "PhoneNumber": "(756) 847-7236" }

For simple demonstration purpose, the Controller only returns Json object pass to it. Here’s the response from Poster:

Obviously, you can also specify your Controller to return any type of result object.

Few important things to note:

  1. This is new feature in ASP.NET MVC 3 (See “JavaScript and AJAX Improvements“).
  2. The JSON object’s strings (‘Firstname’, ‘Lastname’, ‘Email’, and ‘PhoneNumber’) must match ViewModel object’s properties.
  3. ViewModel object’s properties must have “{ get; set; }” method.
  4. Must specify Content Type as “application/json” in the request.
  5. If it’s still not working, check the JSON string to make sure it’s valid one.