可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
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.
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.
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
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?
Should I be concerned about exposing the model information?
回答1:
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\");
}
});
回答2:
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\"}}\'
回答3:
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 });
}
回答4:
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.
回答5:
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
});