Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a View that allows a user to enter/edit data for a new Widget. I'd like to form up that data into a json object and send it to my controller via AJAX so I can do the validation on the server without a postback.

I've got it all working, except I can't figure out how to pass the data so my controller method can accept a complex Widget type instead of individual parameters for each property.

So, if this is my object:

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

I'd like my controller method to look something like this:

public JsonResult Save(Widget widget) {    ... } 

Currently, my jQuery looks like this:

var formData = $("#Form1").serializeArray();  $.post("/Widget/Save",    formData,    function(result){}, "json"); 

My form (Form1) has an input field for each property on the Widget (Id, Name, Price). This works great, but it ultimately passes each property of the Widget as a separate parameter to my controller method.

Is there a way I could "intercept" the data, maybe using an ActionFilterAttribute, and deserialize it to a Widget object before my controller method gets called?

like image 399
MrDustpan Avatar asked Nov 06 '08 05:11

MrDustpan


People also ask

How pass JSON data in MVC?

1) Create an attribute that overrides the OnActionExecuting event handler. 3) use attribute parameters to figure out the type of object you want to stream the data into. 4) deserialize the JSON object into your object.

How pass JSON data to AJAX to controller?

ajax({ type: "POST", url: "DATACRUD. json", data: JSON. stringify({data:"test"}), contentType: "application/json; charset=utf-8", dataType: "json", async: false, //_async, success: function (result) { } }); Ajax successfully invokes the action in a controller, but the parameter is null.

What is JsonResult type in MVC?

What is JsonResult ? JsonResult is one of the type of MVC action result type which returns the data back to the view or the browser in the form of JSON (JavaScript Object notation format).


1 Answers

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; }     } } 
like image 129
MrDustpan Avatar answered Oct 10 '22 19:10

MrDustpan