在父页面上显示错误的 mvc 局部视图
Display mvc partial view with errors on parent page
我有一个包含多个表单的页面,每个表单都是部分表单。我想 post 每个部分都提交。如果有错误,我希望验证错误作为主页的一部分显示在部分中,即如果有错误,我不想只在它自己的页面上看到部分。我说这种行为只有 ajax post 才有可能吗?如果没有 ajax post,我将如何 return 模型状态错误,只是正常形式 post?
编辑:
仍然在自己的页面上看到部分内容
部分 -
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
{
@Html.ValidationMessage("InvalidUserNamePassword")
<fieldset class="fieldset">
<div>
<label for="form-field-user_id">User ID</label>
<span>
@Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text", @id = "form-field-user_id"})
</span>
</div>
</fieldset>
<div class="form-field__button">
<button id="loginButton" type="submit" class="button button--primary">Login</button>
</div>
}
<script>
$('#loginButton').click(function () {
$.ajax({
type: "POST",
url: '@Url.Action("Login", "Account")',
data: $('form').serialize(),
success: function (result) {
if (result.redirectTo) {
window.location.href = result.redirectTo;
} else {
$("#LoginForm").html(result);
}
},
error: function () {
$("#LoginForm").html(result);
}
});
});
</script>
控制器-
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (!ModelState.IsValid)
{
return PartialView("~/Views/Account/_Login.cshtml", model);
}
return Json(new { redirectTo = Url.Action("Index", "Profile") });
}
是的,你说得对 只有 ajax post.
这种行为才有可能
您当前的脚本存在一些问题,这意味着您将无法获得所需的结果。
首先,您的按钮是一个提交按钮,这意味着除了 ajax 调用之外,它还会进行正常的提交,除非您取消默认事件(通过添加 return false;
作为代码的最后一行在你的脚本中)。但是,将按钮类型更改为 type="button"
会更容易
<button id="loginButton" type="button" class="button button--primary">Login</button>
ajax 调用现在将更新现有页面,但它会将返回的部分添加到现有 <form>
元素中,导致嵌套表单无效 html 且不受支持.更改您的 html 以将主视图表单包装在另一个元素中
<div id="LoginFormContainer">
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
{
....
<button id="loginButton" type="button" class="button button--primary">Login</button>
}
</div>
然后修改脚本更新外层元素html
success: function (result) {
if (result.redirectTo) {
window.location.href = result.redirectTo;
} else {
$("#LoginFormContainer").html(result); // modify
}
},
最后,您呈现的动态内容使客户端验证不适用于返回的表单。假设您的属性具有验证属性(例如 Userame
属性 上的 [Required]
属性),您需要在加载内容后重新解析验证器
var form = $('#LoginForm');
....
} else {
$("#LoginFormContainer").html(result);
// reparse validator
form.data('validator', null);
$.validator.unobtrusive.parse(form);
}
您注意到页面上有多个表单,在这种情况下,您的 ajax 选项应该是
data: $('#LoginForm').serialize(),
或者如果您按照上述代码段声明 var form = $('#LoginForm');
,则 data: form.serialize(),
以确保您序列化正确的形式。
旁注:没有真正需要更改文本框的 id
属性(默认情况下它将是 id=Username"
,您可以简单地使用
@Html.LabelFor(x => x.UserName, "User ID")
@Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text" })
或者只是 属性 的 @Html.LabelFor(x => x.UserName)
装饰有 [Display(Name = "User ID")]
我有一个包含多个表单的页面,每个表单都是部分表单。我想 post 每个部分都提交。如果有错误,我希望验证错误作为主页的一部分显示在部分中,即如果有错误,我不想只在它自己的页面上看到部分。我说这种行为只有 ajax post 才有可能吗?如果没有 ajax post,我将如何 return 模型状态错误,只是正常形式 post?
编辑: 仍然在自己的页面上看到部分内容
部分 -
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
{
@Html.ValidationMessage("InvalidUserNamePassword")
<fieldset class="fieldset">
<div>
<label for="form-field-user_id">User ID</label>
<span>
@Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text", @id = "form-field-user_id"})
</span>
</div>
</fieldset>
<div class="form-field__button">
<button id="loginButton" type="submit" class="button button--primary">Login</button>
</div>
}
<script>
$('#loginButton').click(function () {
$.ajax({
type: "POST",
url: '@Url.Action("Login", "Account")',
data: $('form').serialize(),
success: function (result) {
if (result.redirectTo) {
window.location.href = result.redirectTo;
} else {
$("#LoginForm").html(result);
}
},
error: function () {
$("#LoginForm").html(result);
}
});
});
</script>
控制器-
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (!ModelState.IsValid)
{
return PartialView("~/Views/Account/_Login.cshtml", model);
}
return Json(new { redirectTo = Url.Action("Index", "Profile") });
}
是的,你说得对 只有 ajax post.
这种行为才有可能您当前的脚本存在一些问题,这意味着您将无法获得所需的结果。
首先,您的按钮是一个提交按钮,这意味着除了 ajax 调用之外,它还会进行正常的提交,除非您取消默认事件(通过添加 return false;
作为代码的最后一行在你的脚本中)。但是,将按钮类型更改为 type="button"
<button id="loginButton" type="button" class="button button--primary">Login</button>
ajax 调用现在将更新现有页面,但它会将返回的部分添加到现有 <form>
元素中,导致嵌套表单无效 html 且不受支持.更改您的 html 以将主视图表单包装在另一个元素中
<div id="LoginFormContainer">
@using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "LoginForm" }))
{
....
<button id="loginButton" type="button" class="button button--primary">Login</button>
}
</div>
然后修改脚本更新外层元素html
success: function (result) {
if (result.redirectTo) {
window.location.href = result.redirectTo;
} else {
$("#LoginFormContainer").html(result); // modify
}
},
最后,您呈现的动态内容使客户端验证不适用于返回的表单。假设您的属性具有验证属性(例如 Userame
属性 上的 [Required]
属性),您需要在加载内容后重新解析验证器
var form = $('#LoginForm');
....
} else {
$("#LoginFormContainer").html(result);
// reparse validator
form.data('validator', null);
$.validator.unobtrusive.parse(form);
}
您注意到页面上有多个表单,在这种情况下,您的 ajax 选项应该是
data: $('#LoginForm').serialize(),
或者如果您按照上述代码段声明 var form = $('#LoginForm');
,则 data: form.serialize(),
以确保您序列化正确的形式。
旁注:没有真正需要更改文本框的 id
属性(默认情况下它将是 id=Username"
,您可以简单地使用
@Html.LabelFor(x => x.UserName, "User ID")
@Html.TextBoxFor(x => x.Username, new { @class = "form-field__input form-field__input--text" })
或者只是 属性 的 @Html.LabelFor(x => x.UserName)
装饰有 [Display(Name = "User ID")]