我有一个允许用户输入/编辑新小部件数据的视图.我希望将数据形成一个json对象,并通过Ajax将其发送到我的控制器,这样我就可以在没有回发的情况下在服务器上进行验证.

我已经让它们都正常工作了,只是我不知道如何传递数据,所以我的控制器方法可以接受复杂的Widget类型,而不是每个属性的单独参数.

如果这是我的目标:

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

我希望我的控制器方法看起来像这样:

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

目前,我的jQuery如下所示:

var formData = $("#Form1").serializeArray();

$.post("/Widget/Save",
   formData,
   function(result){}, "json");

我的表单(Form1)为小部件上的每个属性(Id、名称、价格)都有一个输入字段.这非常有效,但它最终会将小部件的每个属性作为单独的参数传递给我的控制器方法.

有没有一种方法可以在调用控制器方法之前,使用ActionFilterAttribute"截取"数据,并将其反序列化为小部件对象?

推荐答案

谢谢杰夫,这让我走上了正确的道路.DefaultModelBinder足够聪明,可以为我发挥所有的魔力...我的问题在于我的小部件类型.在我匆忙中,我的类型被定义为:

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

请注意,该类型具有公共字段而不是公共属性.一旦我把它们改成了房产,它就成功了.以下是最终正确运行的源代码:

小装置.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>

家庭控制器.反恐精英:

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; }
    }
}

Asp.net相关问答推荐

如何根据另一个下拉列表中的 Select 从下拉列表中删除一个值?

如何使用 Get-Process powershell 命令通过端口号获取进程的 ID

如何将 viewbag 显示为 html?

为什么微软决定支持 jQuery 如此重要?

ASP.NET web api 无法获取 application/x-www-form-urlencoded HTTP POST

下载功能在 asp.net 的更新面板中不起作用

ASP.NET GridView 第二个标题行跨越主标题行

为什么我在安装 IE8 后无法从 Visual Studio 2005 调试?

如何在集线器类之外获取 SignalR 用户连接 ID?

如何检测 ASP.net 应用程序中的 SqlServer 连接泄漏?

部署后网站需要强制刷新

使用 NancyFx 的好处?

使下拉列表项不可 Select

MVC5 身份验证中的......与主域之间的信任关系失败

在asp.net控件之间动态添加

投票有什么问题?

ASP.NET 5、EF 7 和 SQLite - SQLite 错误 1:没有这样的表:博客

协调 ASP.NET 脚本包和源映射

连接字符串正确时出现实例失败错误

System.Drawing.Image.FromFile() 上的内存不足异常