Alex Rivera | Logout

In ASP.NET MVC, deserialize JSON prior to or in controller's action method

Asked 2009-09-25T00:45:48.873
20

I am working on a website that will post a JSON object (using jQuery Post method) to the server side.

{ 
    "ID" : 1,
    "FullName" : {
       "FirstName" : "John",
       "LastName" : "Smith"
    }
}

At the same time, I wrote classes on the server side for this data structure.

public class User
{
    public int ID { get; set; }
    public Name FullName { get; set;}
}

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

When I run the website with following code in my controller class, the FullName property doesn't get deserialized. What am I doing wrong?

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Submit(User user)
{
    // At this point, user.FullName is NULL. 

    return View();
}
Edit
Report

3 Answers

24

I resolved my problem by implementing an action filter; code sample is provided below. From the research, I learned that there is another solution, model binder, as takepara described above. But I don't really know that pros and cons of doing in either approach.

Thanks to Steve Gentile's blog post for this solution.

public class JsonFilter : ActionFilterAttribute
    {
        public string Parameter { get; set; }
        public Type JsonDataType { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
            {
                string inputContent;
                using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
                {
                    inputContent = sr.ReadToEnd();
                }

                var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
                filterContext.ActionParameters[Parameter] = result;
            }
        }
    }

[AcceptVerbs(HttpVerbs.Post)]
[JsonFilter(Parameter="user", JsonDataType=typeof(User))]
public ActionResult Submit(User user)
{
    // user object is deserialized properly prior to execution of Submit() function

    return View();
}
answered 2009-09-26T04:22:23.317
12

1.create custom model binder

  public class UserModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      User model;

      if(controllerContext.RequestContext.HttpContext.Request.AcceptTypes.Contains("application/json"))
      {
        var serializer = new JavaScriptSerializer();
        var form = controllerContext.RequestContext.HttpContext.Request.Form.ToString();
        model = serializer.Deserialize<User>(HttpUtility.UrlDecode(form));
      }
      else
      {
        model = (User)ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext);
      }

      return model;
    }
  }

2.add model binder in application_start event

  ModelBinders.Binders[typeof(User)] = new UserModelBinder();

3.use jQuery $.get/$.post in view client JavaScript code.

  <% using(Html.BeginForm("JsonData","Home",new{},FormMethod.Post, new{id="jsonform"})) { %>

    <% = Html.TextArea("jsonarea","",new {id="jsonarea"}) %><br />

    <input type="button" id="getjson" value="Get Json" />
    <input type="button" id="postjson" value="Post Json" />
  <% } %>
  <script type="text/javascript">
    $(function() {
      $('#getjson').click(function() {
        $.get($('#jsonform').attr('action'), function(data) {
          $('#jsonarea').val(data);
        });
      });

      $('#postjson').click(function() {
        $.post($('#jsonform').attr('action'), $('#jsonarea').val(), function(data) {
          alert("posted!");
        },"json");
      });
    });
  </script>
answered 2009-09-25T14:18:16.077
5

You could try Json.NET. The documentation is pretty good and it should be able to do what you need. You'll also want to grab JsonNetResult as it returns an ActionResult that can be used in ASP.NET MVC application. It's quite easy to use.

Json.NET also works well with Date serialization. More info regarding that can be found here.

Hope this helps.

answered 2009-09-25T01:57:27.400

Your Answer