如果启用 [AntiForgeryToken],则无法从 JQuery 访问操作方法
Can't access to action method from JQuery if [AntiForgeryToken] is enabled
我有一个可以正常工作的 JQuery 函数,但是如果我在 Action Method 上启用 [AntiForgerToken]
,那么 JQuery 函数无法访问 Action Method,在我的视图中我启用 AntiForgeryToken 的其他片段:
@using (Html.BeginForm("InsertStudent","Students",FormMethod.Post, new { @id="myform"}))
{
@Html.AntiForgeryToken()
视图里面的@Html.AntiForgeryToken()
开不开没关系,JQuery功能正常,问题出在Action Method...
为什么会这样?我错过了什么??我读过在 Post 操作方法上启用 [AntiForgeryToken]
对于安全性非常重要,所以我认为应用程序应该在操作方法和视图的两个地方启用它。
JQuery函数:
function InsertShowStudents() {
var counter = 0;
$.ajax({
type:"post",
url: "/Students/InsertStudent/",
data: { Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
}).done(function (result) {
if (counter==0) {
GetStudents();
CounterStudents();
counter = 1;
}
else {
$("#tableJQuery").append("<tr>"+"<td>"+result.Name+"</td>"+"<td>"+result.LastName+"</td>"+"<td>"+result.Age+"</td>"+"</tr>")
}
//clear the form
$("#myform")[0].reset();
}).error(function () {
$("#divGetStudents").html("An error occurred")
})
}
操作方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult InsertStudent(Student student)
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
//ModelState.Clear();
return RedirectToAction("InsertStudent");
}
return View(student);
}
table 的列:
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
@* <td style="display:none" class="tdStudentID">@Html.DisplayFor(modelItem => item.StudentID)</td> *@
<td>
<img src="~/images/deleteIcon.png" width="20" height="20" class="imgJQuery" data-id="@item.StudentID" />
</td>
<td>
@Html.ActionLink("Details","Details", new { id=item.StudentID})
</td>
</tr>
}
您没有在 ajax 调用中传递令牌的值,因此抛出异常。您可以使用
获取令牌的值
var token = $('[name=__RequestVerificationToken]').val();
并修改您的 ajax 调用以使用
包含它
data: { __RequestVerificationToken: token, Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
但是,只序列化包含令牌的表单会更容易
$.ajax({
type:"post",
url: '@Url.Action("InsertStudent", "Students")', // don't hardcode your url's
data: $('#myform').serialize(),
}).done(function (result) {
旁注:Ajax 调用永远不会重定向(ajax 的全部意义在于保持在同一页面上)因此 return RedirectToAction("InsertStudent");
在您的 InsertStudent()
中不会工作。此外,您的 returning html,因此 .done()
回调中的 $("#tableJQuery").append()
代码将失败。
看来你有一个表格可以添加一个新的 Student
所以你的方法只需要 return 一个 JsonResult
表示成功或其他,如果成功,那么你可以添加根据表单中的值在 table 中添加新行,例如
}).done(function (result) {
if (result) {
var row = $('<tr></tr>');
row.append($('<td></td>').text($("#Name").val()));
... // add other cells
$("#tableJQuery").append(row);
//clear the form
$("#myform")[0].reset();
} else {
// Oops something went wrong
}
})
我有一个可以正常工作的 JQuery 函数,但是如果我在 Action Method 上启用 [AntiForgerToken]
,那么 JQuery 函数无法访问 Action Method,在我的视图中我启用 AntiForgeryToken 的其他片段:
@using (Html.BeginForm("InsertStudent","Students",FormMethod.Post, new { @id="myform"}))
{
@Html.AntiForgeryToken()
视图里面的@Html.AntiForgeryToken()
开不开没关系,JQuery功能正常,问题出在Action Method...
为什么会这样?我错过了什么??我读过在 Post 操作方法上启用 [AntiForgeryToken]
对于安全性非常重要,所以我认为应用程序应该在操作方法和视图的两个地方启用它。
JQuery函数:
function InsertShowStudents() {
var counter = 0;
$.ajax({
type:"post",
url: "/Students/InsertStudent/",
data: { Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
}).done(function (result) {
if (counter==0) {
GetStudents();
CounterStudents();
counter = 1;
}
else {
$("#tableJQuery").append("<tr>"+"<td>"+result.Name+"</td>"+"<td>"+result.LastName+"</td>"+"<td>"+result.Age+"</td>"+"</tr>")
}
//clear the form
$("#myform")[0].reset();
}).error(function () {
$("#divGetStudents").html("An error occurred")
})
}
操作方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult InsertStudent(Student student)
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
//ModelState.Clear();
return RedirectToAction("InsertStudent");
}
return View(student);
}
table 的列:
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
@* <td style="display:none" class="tdStudentID">@Html.DisplayFor(modelItem => item.StudentID)</td> *@
<td>
<img src="~/images/deleteIcon.png" width="20" height="20" class="imgJQuery" data-id="@item.StudentID" />
</td>
<td>
@Html.ActionLink("Details","Details", new { id=item.StudentID})
</td>
</tr>
}
您没有在 ajax 调用中传递令牌的值,因此抛出异常。您可以使用
获取令牌的值var token = $('[name=__RequestVerificationToken]').val();
并修改您的 ajax 调用以使用
包含它data: { __RequestVerificationToken: token, Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
但是,只序列化包含令牌的表单会更容易
$.ajax({
type:"post",
url: '@Url.Action("InsertStudent", "Students")', // don't hardcode your url's
data: $('#myform').serialize(),
}).done(function (result) {
旁注:Ajax 调用永远不会重定向(ajax 的全部意义在于保持在同一页面上)因此 return RedirectToAction("InsertStudent");
在您的 InsertStudent()
中不会工作。此外,您的 returning html,因此 .done()
回调中的 $("#tableJQuery").append()
代码将失败。
看来你有一个表格可以添加一个新的 Student
所以你的方法只需要 return 一个 JsonResult
表示成功或其他,如果成功,那么你可以添加根据表单中的值在 table 中添加新行,例如
}).done(function (result) {
if (result) {
var row = $('<tr></tr>');
row.append($('<td></td>').text($("#Name").val()));
... // add other cells
$("#tableJQuery").append(row);
//clear the form
$("#myform")[0].reset();
} else {
// Oops something went wrong
}
})