在 jquery 中使用 AJAX Post 从强类型 MVC3 视图传递模型的正确方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5980389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 20:09:29  来源:igfitidea点击:

Proper way to use AJAX Post in jquery to pass model from strongly typed MVC3 view

asp.net-mvc-3jquery

提问by John Stone

I'm a novice web programmer so please forgive me if some of my "jargon" is not correct. I've got a project using ASP.NET using the MVC3 framework.

我是一个新手网络程序员,所以如果我的一些“行话”不正确,请原谅我。我有一个使用 ASP.NET 使用 MVC3 框架的项目。

I am working on an admin view where the admin will modify a list of equipment. One of the functions is an "update" button that I want to use jquery to dynamically edit the entry on the webpage after sending a post to the MVC controller.

我正在处理管理员视图,管理员将在其中修改设备列表。其中一个功能是“更新”按钮,我想在向 MVC 控制器发送帖子后使用 jquery 动态编辑网页上的条目。

I presume this approach is "safe" in a single admin setting where there is minimal concern of the webpage getting out of sync with the database.

我认为这种方法在单个管理设置中是“安全的”,其中网页与数据库不同步的担忧最小。

I've created a view that is strongly typed and was hoping to pass the model data to the MVC control using an AJAX post.

我创建了一个强类型视图,并希望使用 AJAX 帖子将模型数据传递给 MVC 控件。

In the following post, I found something that is similar to what I am looking at doing: JQuery Ajax and ASP.NET MVC3 causing null parameters

在下面的帖子中,我发现了一些类似于我正在做的事情: JQuery Ajax 和 ASP.NET MVC3 导致空参数

I will use the code sample from the above post.

我将使用上述帖子中的代码示例。

Model:

模型:

public class AddressInfo 
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

Controller:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Check(AddressInfo addressInfo)
    {
        return Json(new { success = true });
    }
}

script in View:

视图中的脚本:

<script type="text/javascript">
var ai = {
    Address1: "423 Judy Road",
    Address2: "1001",
    City: "New York",
    State: "NY",
    ZipCode: "10301",
    Country: "USA"
};

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: JSON.stringify(ai),
    contentType: 'application/json; charset=utf-8',
    success: function (data.success) {
        alert(data);
    },
    error: function () {
        alert("error");
    }
});
</script>

I have not had a chance to use the above yet. But I was wondering if this was the "best" method to pass the model data back to the MVC control using AJAX?

我还没有机会使用上面的。但我想知道这是否是使用 AJAX 将模型数据传递回 MVC 控件的“最佳”方法?

Should I be concerned about exposing the model information?

我应该担心暴露模型信息吗?

采纳答案by Craig M

You can skip the var declaration and the stringify. Otherwise, that will work just fine.

您可以跳过 var 声明和 stringify。否则,这将工作得很好。

$.ajax({
    url: '/home/check',
    type: 'POST',
    data: {
        Address1: "423 Judy Road",
        Address2: "1001",
        City: "New York",
        State: "NY",
        ZipCode: "10301",
        Country: "USA"
    },
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
        alert(data.success);
    },
    error: function () {
        alert("error");
    }
});

回答by Jazaret

I found 3 ways to implement this:

我找到了 3 种实现方法:

C# class:

C# 类:

public class AddressInfo {
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }
}

Action:

行动:

[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
    return Json(new { success = true });
}

JavaScriptyou can do it three ways:

JavaScript你可以通过三种方式做到:

1) Query String:

1) 查询字符串:

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serialize(),
    type: 'POST',
});

Data here is a string.

这里的数据是一个字符串。

"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"

"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"

2) Object Array:

2)对象数组:

$.ajax({
    url: '/en/Home/Check',
    data: $('#form').serializeArray(),
    type: 'POST',
});

Data here is an array of key/value pairs :

这里的数据是一个键/值对数组:

=[{name: 'Address1', value: 'blah'}, {name: 'Address2', value: 'blah'}, {name: 'City', value: 'blah'}, {name: 'State', value: 'blah'}, {name: 'ZipCode', value: 'blah'}, {name: 'Country', value: 'blah'}]

3) JSON:

3)JSON:

$.ajax({
      url: '/en/Home/Check',
      data: JSON.stringify({ addressInfo:{//missing brackets
          Address1: $('#address1').val(),
          Address2: $('#address2').val(),
          City: $('#City').val(),
          State: $('#State').val(),
          ZipCode: $('#ZipCode').val()}}),
      type: 'POST',
      contentType: 'application/json; charset=utf-8'
});

Data here is a serialized JSON string. Note that the name has to match the parameter name in the server!!

这里的数据是一个序列化的 JSON 字符串。请注意,名称必须与服务器中的参数名称匹配!!

='{"addressInfo":{"Address1":"blah","Address2":"blah","City":"blah","State":"blah", "ZipCode", "blah", "Country", "blah"}}'

回答by Sanchitos

This is the way it worked for me:

这是它对我有用的方式:

$.post("/Controller/Action", $("#form").serialize(), function(json) {       
        // handle response
}, "json");

[HttpPost]
public ActionResult TV(MyModel id)
{
    return Json(new { success = true });
}

回答by Adam Tuliper - MSFT

what you have is fine - however to save some typing, you can simply use for your data

你所拥有的很好 - 但是为了节省一些输入,你可以简单地使用你的数据

data: $('#formId').serialize()

see http://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/for details, the syntax is pretty basic.

有关详细信息,请参阅http://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/,语法非常基本。

回答by blubberbo

If using MVC 5 read this solution!

如果使用 MVC 5,请阅读此解决方案!

I know the question specifically called for MVC 3, but I stumbled upon this page with MVC 5 and wanted to post a solution for anyone else in my situation. I tried the above solutions, but they did not work for me, the Action Filter was never reached and I couldn't figure out why. I am using version 5 in my project and ended up with the following action filter:

我知道专门针对 MVC 3 提出的问题,但我偶然发现了 MVC 5 的这个页面,并想为我这种情况的其他人发布解决方案。我尝试了上述解决方案,但它们对我不起作用,从未达到动作过滤器,我无法弄清楚原因。我在我的项目中使用了第 5 版,最终得到了以下操作过滤器:

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

namespace SydHeller.Filters
{
    public class ValidateJSONAntiForgeryHeader : FilterAttribute, IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            string clientToken = filterContext.RequestContext.HttpContext.Request.Headers.Get(KEY_NAME);
            if (clientToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Header does not contain {0}", KEY_NAME));
            }

            string serverToken = filterContext.HttpContext.Request.Cookies.Get(KEY_NAME).Value;
            if (serverToken == null)
            {
                throw new HttpAntiForgeryException(string.Format("Cookies does not contain {0}", KEY_NAME));
            }

            System.Web.Helpers.AntiForgery.Validate(serverToken, clientToken);
        }

        private const string KEY_NAME = "__RequestVerificationToken";
    }
}

-- Make note of the using System.Web.Mvcand using System.Web.Mvc.Filters, not the httplibraries (I think that is one of the things that changed with MVC v5. --

-- 记下using System.Web.Mvcand using System.Web.Mvc.Filters,而不是http库(我认为这是 MVC v5 改变的事情之一。--

Then just apply the filter [ValidateJSONAntiForgeryHeader]to your action (or controller) and it should get called correctly.

然后只需将过滤器[ValidateJSONAntiForgeryHeader]应用于您的操作(或控制器),它就会被正确调用。

In my layout page right above </body>I have @AntiForgery.GetHtml();

在我上面的布局页面中,</body>我有@AntiForgery.GetHtml();

Finally, in my Razor page, I do the ajax call as follows:

最后,在我的 Razor 页面中,我按如下方式执行 ajax 调用:

var formForgeryToken = $('input[name="__RequestVerificationToken"]').val();

$.ajax({
  type: "POST",
  url: serviceURL,
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  data: requestData,
  headers: {
     "__RequestVerificationToken": formForgeryToken
  },
     success: crimeDataSuccessFunc,
     error: crimeDataErrorFunc
});