[asp.net] view 에서 controller 로 json 객체를 파라미터로서 넘기는 방법

Posted by RAY.D
2015. 4. 27. 14:09 Web/ASP.NET MVC
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.




ASP.NET MVC How to pass JSON object from View to Controller as Parameter


I have a complex JSON object which is sent to the View without any issues (as shown below) but I cannot work out how Serialize this data back to a .NET object when it is passed back to the controller through an AJAX call. Details of the various parts are below.

   var ObjectA = {
        "Name": 1,
        "Starting": new Date(1221644506800),

        "Timeline": [
            {
                "StartTime": new Date(1221644506800),
                "GoesFor": 200

            }
            ,
            {
                "StartTime": new Date(1221644506800),
                "GoesFor": 100

            }

        ]
    };

I am not sure how this object can be passed to a Controller Method, I have this method below where the Timelines object mirrors the above JS object using Properties.

public JsonResult Save(Timelines person)

The jQuery I am using is:

        var encoded = $.toJSON(SessionSchedule);

        $.ajax({
            url: "/Timeline/Save",
            type: "POST",
            dataType: 'json',
            data: encoded,
            contentType: "application/json; charset=utf-8",
            beforeSend: function() { $("#saveStatus").html("Saving").show(); },
            success: function(result) {
                alert(result.Result);
                $("#saveStatus").html(result.Result).show();
            }
        });

I have seen this question which is similar, but not quite the same as I am not using a forms to manipulate the data. http://stackoverflow.com/questions/267707/how-to-pass-complex-type-using-json-to-asp-net-mvc-controller

I have also seen references to using a 'JsonFilter' to manually deserialize the JSON, but was wondering if there is a way to do it nativly though ASP.NET MVC? Or what are the best practices for passing data in this way?







Edit:

This method should no longer be needed with the arrival of MVC 3, as it will be handled automatically -http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx


You can use this ObjectFilter:

    public class ObjectFilter : ActionFilterAttribute {

    public string Param { get; set; }
    public Type RootType { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json")) {
            object o =
            new DataContractJsonSerializer(RootType).ReadObject(filterContext.HttpContext.Request.InputStream);
            filterContext.ActionParameters[Param] = o;
        }

    }
}

You can then apply it to your controller methods like so:

    [ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
    public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }

So basically, if the content type of the post is "application/json" this will spring into action and will map the values to the object of type you specify.






















This answer is a follow up to DaRKoN_'s answer that utilized the object filter:

[ObjectFilter(Param = "postdata", RootType = typeof(ObjectToSerializeTo))]
    public JsonResult ControllerMethod(ObjectToSerializeTo postdata) { ... }

I was having a problem figuring out how to send multiple parameters to an action method and have one of them be the json object and the other be a plain string. I'm new to MVC and I had just forgotten that I already solved this problem with non-ajaxed views.

What I would do if I needed, say, two different objects on a view. I would create a ViewModel class. So say I needed the person object and the address object, I would do the following:

public class SomeViewModel()
{
     public Person Person { get; set; }
     public Address Address { get; set; }
}

Then I would bind the view to SomeViewModel. You can do the same thing with JSON.

[ObjectFilter(Param = "jsonViewModel", RootType = typeof(JsonViewModel))] // Don't forget to add the object filter class in DaRKoN_'s answer.
public JsonResult doJsonStuff(JsonViewModel jsonViewModel)
{
     Person p = jsonViewModel.Person;
     Address a = jsonViewModel.Address;
     // Do stuff
     jsonViewModel.Person = p;
     jsonViewModel.Address = a;
     return Json(jsonViewModel);
}

Then in the view you can use a simple call with JQuery like this:

var json = { 
    Person: { Name: "John Doe", Sex: "Male", Age: 23 }, 
    Address: { Street: "123 fk st.", City: "Redmond", State: "Washington" }
};

$.ajax({
     url: 'home/doJsonStuff',
     type: 'POST',
     contentType: 'application/json',
     dataType: 'json',
     data: JSON.stringify(json), //You'll need to reference json2.js
     success: function (response)
     {
          var person = response.Person;
          var address = response.Address;
     }
});