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?

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

Post an Array of Objects via JSON to ASP.Net MVC3

The problem was that the properties in the models that were in the List did not have get/set on their public properties. Put another way, MVC3's automatic JSON binding only works on object properties that have get and set.

This will not bind:

public string Str;

This will bind:

public string Str { get; set; }

Post an array of complex objects with JSON, JQuery to ASP.NET MVC Controller

You can serialize the form as Vikas posted, or you could use a stringify function if you'd prefer to walk the page (as you are currently doing) and use the postData array.

On the controller, you'll need to handle the json string. You can use the System.Web.Script.Serialization.JavaScriptSerializer class to deserialize it. If you have an object that maps to the data you're passing, you can use the Deserialize method. If you don't, you can still use DeserializeObject, however that gives you a Dictionary<string, string> collection that you'll have to walk through to get your data. Not exactly fun (trust me), but it works.

Post an array of complex objects with JSON, MVC model is do not bind

Model binding is failing because those 2 properties are currently private(which is the default when you don't specify anything explicitly).

Change the 2 properties to public so that model binder can set the values of those.

public class MixModel
{
public string MixName { get; set; }
public string MixDesc { get; set; }
public float Price { get; set; }
public DiseaseMix[] DiseaseMixs { get; set; } //DiseaseMix EntityFramework entity
public MixProduct[] MixProducts { get; set; } //MixProduct EF

}

I also suggests to not mix your view models with entities generated by your ORM. That creates a tightly coupled solution.

Passing NESTED Complex json to MVC Controllers

I think you need to stringified your data

var dataToSend={
'arrayData':simpleArray,
'arrayOfarrayData':arrayOfarrays
};

$.ajax({
url: '/Home/Save',
data: JSON.stringify(dataToSend),
type: 'POST',
contentType: 'application/json',
dataType: 'json',
traditional:true,
cache: false,
success: function (result) {
}
});

How to pass complex type using json to ASP.NET MVC controller

Thanks Jeff, that got me on the right path. The DefaultModelBinder is smart enough to do all the magic for me...my problem was in my Widget type. In my haste, my type was defined as:

public class Widget
{
public int Id;
public string Name;
public decimal Price;
}

Notice that the type has public fields instead of public properties. Once I changed those to properties, it worked. Here's the final source code that works correctly:

Widget.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Widget.aspx.cs" Inherits="MvcAjaxApp2.Views.Home.Widget" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<script src="../../Scripts/jquery-1.2.6.js" type="text/javascript"></script>
<script type="text/javascript">
function SaveWidget()
{
var formData = $("#Form1").serializeArray();

$.post("/Home/SaveWidget",
formData,
function(data){
alert(data.Result);
}, "json");
}
</script>
<form id="Form1">
<input type="hidden" name="widget.Id" value="1" />
<input type="text" name="widget.Name" value="my widget" />
<input type="text" name="widget.Price" value="5.43" />
<input type="button" value="Save" onclick="SaveWidget()" />
</form>
</asp:Content>

HomeController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;

namespace MvcAjaxApp2.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}

public ActionResult About()
{
ViewData["Title"] = "About Page";
return View();
}

public ActionResult Widget()
{
ViewData["Title"] = "Widget";
return View();
}

public JsonResult SaveWidget(Widget widget)
{
// Save the Widget
return Json(new { Result = String.Format("Saved widget: '{0}' for ${1}", widget.Name, widget.Price) });
}
}
public class Widget
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}

jQuery post array - ASP.Net MVC 4

MVC detects what type of data it receive by contentType. Here is working example:

$(function () {
$.ajax({
type: 'Post',
dataType: 'json',
url: '/Workflow/Home/UpdateStepPositions',
data: JSON.stringify({ steps: ['1', '2', '3'] }),
contentType: 'application/json; charset=utf-8',
async: false,
success: function (data) {
console.debug(data);
},
error: function (data) {
console.debug(data);
}
});
});

Now everything ok with request:

Content-Type:        application/json; charset=utf-8
X-Requested-With: XMLHttpRequest

and response:

Content-Type:        application/json; charset=utf-8

Post Array as JSON to MVC Controller

$.post() doesn't allow you to set the content type of your AJAX call - you might find (if you use Fiddler) that your Json string is being sent with a content-type of "application/x-www-form-urlencoded" (the default setting) which then causes Asp.Net MVC to incorrectly interpret your data packet.

Can you try using $.ajax() instead, and set the content type to "application/json"?

http://api.jquery.com/jQuery.ajax/

Binding MVC model in controller which has a complex array

Turns out just need to add a line and property reference, and add each variable separately.

        for (var i in gridData) {
for (var j in gridData[i]) {
data.push({ name: 'GridRows[' + i + '].' + j, value: gridData[i][j] });
}
}

Edit: Just thought I'd post my updated helper method I wrote a while ago for this.

function serializeArray(obj, data, name) {
/// <summary>Turns an object into an MVC standard array of values </summary>
/// <param name="obj" type="Object">Object to serialise (required)</param>
/// <param name="data" type="Array">Array to append data to end of (optional)</param>
/// <param name="name" type="String">Name prefix for all entries (optional/ignore)</param>

if (!data || !(data instanceof Array)) {
data = [];
}
if (obj instanceof Array) {
if (!name) {
throw "Need an object name when converting an array";
}
for (var index = 0; index < obj.length; index++) {
data = serializeArray(obj[index], data, name + '[' + index + ']');
}
} else if (obj instanceof Object) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
data = serializeArray(obj[property], data, name ? (name + '.' + property) : property);
}
}
} else {
data.push({ name: name, value: obj });
}
return data;
}


Related Topics



Leave a reply



Submit