How to post an array of complex objects with JSON, jQuery to ASP.NET MVC Controller? How to post an array of complex objects with JSON, jQuery to ASP.NET MVC Controller? json json

How to post an array of complex objects with JSON, jQuery to ASP.NET MVC Controller?


I've found an solution. I use an solution of Steve Gentile, jQuery and ASP.NET MVC – sending JSON to an Action – Revisited.

My ASP.NET MVC view code looks like:

function getplaceholders() {        var placeholders = $('.ui-sortable');        var results = new Array();        placeholders.each(function() {            var ph = $(this).attr('id');            var sections = $(this).find('.sort');            var section;            sections.each(function(i, item) {                var sid = $(item).attr('id');                var o = { 'SectionId': sid, 'Placeholder': ph, 'Position': i };                results.push(o);            });        });        var postData = { widgets: results };        var widgets = results;        $.ajax({            url: '/portal/Designer.mvc/SaveOrUpdate',            type: 'POST',            dataType: 'json',            data: $.toJSON(widgets),            contentType: 'application/json; charset=utf-8',            success: function(result) {                alert(result.Result);            }        });    };

and my controller action is decorated with an custom attribute

[JsonFilter(Param = "widgets", JsonDataType = typeof(List<PageDesignWidget>))]public JsonResult SaveOrUpdate(List<PageDesignWidget> widgets

Code for the custom attribute can be found here (the link is broken now).

Because the link is broken this is the code for the JsonFilterAttribute

public class JsonFilter : ActionFilterAttribute{    public string Param { 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[Param] = result;        }    }}

JsonConvert.DeserializeObject is from Json.NET

Link: Serializing and Deserializing JSON with Json.NET


Action Filters, jquery stringify, bleh...

Peter, this functionality is native to MVC. That's one of things that makes MVC so great.

$.post('SomeController/Batch', { 'ids': ['1', '2', '3']}, function (r) {   ...});

And in the action,

[HttpPost]public ActionResult Batch(string[] ids){}

Works like a charm:

enter image description here

If you're using jQuery 1.4+, then you want to look into setting traditional mode:

jQuery.ajaxSettings.traditional = true;

As described here: http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/02/24/jquery-1-4-breaks-asp-net-mvc-actions-with-array-parameters

This even works for complex objects. If you're interested, you should look into the MVC documentation about Model Binding: http://msdn.microsoft.com/en-us/library/dd410405.aspx


In .NET4.5, MVC 5 no need for widgets.

Javascript:

object in JS:enter image description here

mechanism that does post.

    $('.button-green-large').click(function() {        $.ajax({            url: 'Quote',            type: "POST",            dataType: "json",            data: JSON.stringify(document.selectedProduct),            contentType: 'application/json; charset=utf-8',        });    });

C#

Objects:

public class WillsQuoteViewModel{    public string Product { get; set; }    public List<ClaimedFee> ClaimedFees { get; set; }}public partial class ClaimedFee //Generated by EF6{    public long Id { get; set; }    public long JourneyId { get; set; }    public string Title { get; set; }    public decimal Net { get; set; }    public decimal Vat { get; set; }    public string Type { get; set; }    public virtual Journey Journey { get; set; }}

Controller:

[AcceptVerbs(HttpVerbs.Post)]public ActionResult Quote(WillsQuoteViewModel data){....}

Object received:

enter image description here

Hope this saves you some time.