显然是一个老生常谈的话题,但我无法通过仔细阅读以前的帖子提出解决方案。希望有人能告诉我这样做的"正确方法",因为我需要做很多事情。
主要问题:当 Ajax.Beginform post ModelState 无效时,它仍然会触发 OnSuccess 方法。我知道这是正确的行为,但我的 OnSuccess 方法只有在(去图)帖子"成功"时才有意义。
在这种情况下,如何最好地管理带有验证错误的重新显示表单?如何从控制器返回 success=false 以及要重新显示的视图?
这与这个问题没有特别关系,但仅供参考,我在这里所做的与尝试在 Bootstrap modal 中显示表单有点相似,我放弃了。
1) 通过 AJAX 调用控制器以在div 中加载表单。
$(function addpaneevent() {
$('.addpane').on("click", function () {
var url = '/QuizPane/QuickPane?quizId=' + $(this).data("quizid");
$.ajax({
url: url,
type: 'GET',
contentType: 'application/json',
success: function (result) {
$('#overlay').html(result);
},
error: function (result) {
console.log("bummer",result);
}
});
});
});
2) 返回包含表单的部分视图
public ActionResult QuickPane(int quizId)
{
var model = *querytogetmodel*
return PartialView("QuickPane",model);
}
@using (Ajax.BeginForm("QuickPane", "QuizPane", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updatePaneList(data)",
OnFailure = "massivefail(data)",
}))
{
@Html.ValidationSummary(true)
<fieldset>
@Html.HiddenFor(model => model.QuizID)
<div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.TextBoxFor(model => model.Title, new { @autofocus = "autofocus" })
@Html.ValidationMessageFor(model => model.Title)
</div>
...more of the same
<input type="submit" value="Create" class="btn btn-primary"/>
</fieldset>
}
3) 在提交呼叫帖子时
[HttpPost]
public ActionResult QuickPane(QuizPane quizpane)
{
if (ModelState.IsValid)
{
db.QuizPanes.Add(quizpane);
db.SaveChanges();
return PartialView("_quizpanelist", quizpane);
}
return View(quizpane); //tried a few different things here
}
4) 成功后,我将新记录添加到表中并删除包含输入表单的div。
function updatePaneList(data) {
$("#overlay").remove();
var rowcount = $(".expanded #panetable tr:last").count;
$('.expanded #panetable tbody:last').append(data);
};
我通过执行以下操作解决了这个问题......虽然我不知道这是否是处理它的建议方法。 此外,在这两种情况下都应返回分部视图。
在返回分部视图之前,添加以下行
Response.AppendHeader("X-Error", "true")
然后在你的JavaScript成功
function doOnSuccess(data, status, xhr) {
if (xhr.getResponseHeader('X-Error')) {
//validation error occurred
}
else
{
//validation error did not occur
}
}
而不是使用Ajax.BeginForm,我会使用普通形式并使用ajax调用。
$(document).on('click', '.btn-primary', function(){
$.ajax({
url: '@Url.Action('QuickPane', 'QuizPane')',
type: 'post',
data: {
Title: $('#Title').val()
}
success: function(result){
//Do Something
}
error: function(result){
//Display error
}
});
});
然后在控制器中返回 JSON 而不是部分视图,您可以设置这样的错误 ASP.NET 从 MVC 返回 Json 错误或像这样成功 ExtJS:如何使用 asp.net mvc 返回带有数据的 json 成功希望这有所帮助。
这是因为OnSuccess
vs OnFailure
没有以任何方式连接到ModeState.IsValid
。
根据AjaxOptions
文档:
OnSuccess
:如果响应状态在 200 范围内,则调用此函数。
OnFailure
:如果响应状态不在 200 范围内,则调用此函数。
换句话说,您必须手动指定在返回 ActionResult 时失败,方法是更改Response.StatusCode
然后返回 OnFailure
js 方法中期望的任何值。
[HttpPost]
public ActionResult Search(Person model)
{
if (ModelState.IsValid) {
// if valid, return a HTML view inserted by AJAX helper
var results = PersonRepository.Get(model)
return PartialView("Resulsts", vm);
} else {
// if invalid, return a JSON object and handle with OnFailure method
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { errors = ModelState.Values.SelectMany(v => v.Errors) });
}
}
延伸阅读:
- MVC 4 Ajax.BeginForm and ModelState.AddModelError
- ASP.NET MVC "Ajax.BeginForm" 执行 OnSuccess,即使模型无效
只需在结果的成功中使用 if/else
$("#SaveStudentRecord").click(function () {
var data = $("#SubmitForm").serialize();
$.ajax({
method: "POST",
url: '@(Url.Action("EditAdd", "Ucesnik"))',
data: data,
success: function (result) {
if (result.success) {
alert("Success!..");
window.location.href = "/Ucesnik/GetUcesnici";
$("#MyModal").modal("hide");
}
else {
alert("Not successful");
}
}
})
})