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

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

我的工作在一个管理员视图,其中管理员将修改设备清单。其中一个函数是“ update”按钮,我想使用 jquery 在向 MVC 控制器发送文章后动态地编辑网页上的条目。

我认为这种方法是“安全的”在一个单一的管理设置,其中有最小的关注网页失去同步的数据库。

我已经创建了一个强类型的视图,希望通过 AJAX 帖子将模型数据传递给 MVC 控件。

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

我将使用上面文章中的代码示例。

型号:

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

总监:

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


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

视图中的脚本:

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

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

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

232787 次浏览

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

$.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");
}
});

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.

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

I found 3 ways to implement this:

C# class:

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

JavaScript you can do it three ways:

1) Query String:

$.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"

2) Object Array:

$.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:

$.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!!

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

If using MVC 5 read this solution!

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:

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.Mvc and using System.Web.Mvc.Filters, not the http libraries (I think that is one of the things that changed with MVC v5. --

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

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

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

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