我有一個javascript函數,用於對我的控制器函數執行Ajax調用。 javascript足夠通用,我可以將它用於多個控件。我有兩個使用腳本的區域。一個工作,一個不工作。我相信這是被調用的MVC控制器的足跡。javascript調用了類似的MVC操作,AntiForgery可以在其中一個上工作,而不是其他工作
的JavaScript看起來像這樣:
$(Document).on("click",".delete-link",function (event) {
var deleteLink = $(this);
deleteLink.hide();
var confirmButton = deleteLink.siblings(".delete-confirm");
confirmButton.show();
var cancelDelete = function() {
removeEvents();
showDeleteLink();
};
var deleteItem = function() {
removeEvents();
confirmButton.hide();
var url = '/' + confirmButton.attr('data-delete-controller') + '/' + confirmButton.attr('data-delete-action') + '/' + confirmButton.attr('data-delete-id');
$.post(
url,
AddAntiForgeryToken({ id: confirmButton.attr('data-delete-id') }))
.done(function() {
var parentRow = deleteLink.closest(".removable-row");//"tr:first, li:first");
parentRow.fadeOut('fast', function() {
parentRow.remove();
});
}).fail(function (data) {
alert("error");
});
return false;
};
var removeEvents = function() {
confirmButton.off("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).off("keypress", onKeyPress);
};
var showDeleteLink = function() {
confirmButton.hide();
deleteLink.show();
};
var onKeyPress = function (e) {
//Cancel if escape key pressed
if (e.which == 27) {
cancelDelete();
}
};
confirmButton.on("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).on("keypress", onKeyPress);
return false;
});
AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};
所以MVC視圖和控制器的行動,工作是這樣定義的:
<div class="row">
@Html.HiddenFor(model => model.CustomFieldOptionId)
@Html.HiddenFor(model => model.CustomFieldId)
@Html.HiddenFor(model => model.SortOrder, new { @class = "SortOrder" })
@Html.HiddenFor(model => model.IsActive)
@Html.ValidationMessageFor(model => model.OptionLabel, "", new { @class = "text-danger" })
<div class="col-md-2">
@Html.LabelFor(model => model.OptionLabel, htmlAttributes: new { @class = "control-label" })
</div>
<div class="col-md-7">
@Html.EditorFor(model => model.OptionLabel, new { htmlAttributes = new { @class = "form-control" } })
</div>
<div class="col-md-3">
<input type="button" value="Delete" class="btn delete-link" />
<div class="btn btn-primary delete-confirm" style="display: none"
data-delete-id="@Model.CustomFieldOptionId"
data-delete-controller="customforms"
data-delete-action="_OptionEditorRowDelete">Confirm Delete</div>
</div>
</div>
控制器:
[HttpPost, ActionName("_OptionEditorRowDelete")]
[ValidateAntiForgeryToken]
public ActionResult _OptionEditorRowDelete(int id)
{
var custFieldOption = db.CustomFieldOptions.Find(id);
if (custFieldOption == null) return null;
custFieldOption.IsActive = false;
db.Entry(custFieldOption).State = EntityState.Modified;
db.SaveChanges();
return null;
}
的一個不工作定義如下:
@foreach (var item in Model) {
<tr>
<td>
@Html.HiddenFor(modelItem => item.ProfileId)
@Html.DisplayFor(modelItem => item.ProfileIdentifierValue)
</td>
<td>
@Html.DisplayFor(modelItem => item.IsPrimary)
</td>
<td>
@Html.ActionLink("Edit", "profileemailsedit", new { id = item.ProfileIdentifierId }) |
@Html.ActionLink("Delete", "_ProfileEmailsDelete", new { id = item.ProfileIdentifierId }, new { @class = "delete-link" })
<a class="delete-link" href="@Url.Action("_ProfileEmailsDelete", new { id = item.ProfileIdentifierId })">Delete</a>
<input type="button" value="Delete" class="btn delete-link" />
<div class="btn btn-primary delete-confirm" style="display: none"
data-delete-id="@item.ProfileIdentifierId"
data-delete-controller="profiles"
data-delete-action="_ProfileEmailsDelete">Confirm Delete</div>
</td>
</tr>
}
控制器:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _ProfileEmailsDelete(int id)
{
var profIdentifier = db.ProfileIdentifier.Find(id);
if (profIdentifier == null) return null;
profIdentifier.IsActive = false;
db.Entry(profIdentifier).State = EntityState.Modified;
db.SaveChanges();
return null;
}
正如你所看到的控制器非常相似。然而,_ProfileEmailsDelete得到的這個JavaScript錯誤:服務器500錯誤的
POST http://localhost:63595/profiles/_ProfileEmailsDelete/168 500 (Internal Server Error)
部分是:
[HttpAntiForgeryException]: The required anti-forgery form field "__RequestVerificationToken" is not present. at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken) at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext) at System.Web.Helpers.AntiForgery.Validate()
我不知道爲什麼防僞工作的一個,而不是其他。