我现在已经开始工作了几天,并且不能像我期望的那样让它工作。 我看了很多例子,但我必须误解一些事情。
我所拥有的是一个Bootstrap模态,它可以加载局部视图。我要做的是验证 (希望客户端)在模态中的@ValidationSummary中显示任何错误。最大的问题 我有的是,当出现错误时,它不是在原始模态中显示,而是基本上加载模态 新页面中的局部视图。验证摘要已正确填充,但它没有任何样式加上它 在那一点上不是模态。
*注意:我目前没有使用AJAX来加载模态。我最终会得到那个,但我不太舒服 还有AJAX,我想先让它工作,然后我可以回来重构AJAX。
_Layout.cshtml - 我发现了一个例子,说我需要在加载Modal时加载JS.unobtrusive。我在假设 我正确地做到了,但我可能会在那里遗漏一些东西。
<div id="modal-container" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
<script type="text/javascript">
//**** Bootstrap Modal - used with Partial Views ***********************
$(function () {
// Initalize modal dialog
// attach modal-container bootstrap attributes to links with .modal-link class.
// when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
$('body').on('click', '.modal-link', function (e) {
e.preventDefault();
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
//load the unobtrusive JS code
$jQval.unobtrusive.parse($modal-container);
var $form = $modal-container.find("form");
$.validator.unobtrusive.parse($form);
});
// Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears
$('body').on('click', '.modal-close-btn', function () {
$('#modal-container').modal('hide');
});
//clear modal cache, so that new content can be loaded
$('#modal-container').on('hidden.bs.modal', function () {
$(this).removeData('bs.modal');
});
$('#CancelModal').on('click', function () {
return false;
});
});
_PasswordReset.cshtml
div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4>Reset your Password</h4>
</div>
<div class="modal-body">
<div class="form-horizontal">
@using (Html.BeginForm("PasswordReset", "Member", FormMethod.Post))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(false, "", new { @class = "alert alert-danger" })
<!-- BEGIN HIDDEN FIELDS AREA -->
@Html.HiddenFor(model => model.MemberId)
<!-- END HIDDEN FIELDS AREA -->
<div class="form-group">
<label class="control-label col-xs-3">Password</label>
<div class="col-md-9">
@Html.TextBoxFor(c => c.Password, new { Class = "form-control", placeholder = "New Password", autofocus = "" })
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-3">Confirm</label>
<div class="col-md-9">
@Html.TextBoxFor(c => c.PasswordConfirm, new { Class = "form-control", placeholder = "Confirm Password" })
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-3 col-xs-9">
<button type="submit" id="approve-btn" class="btn btn-primary">
Reset
</button>
<input type="button" class="btn btn-default" value="Cancel" data-dismiss="modal" />
</div>
</div>
}
</div>
</div>
控制器 - 我假设如果模型无效,那么我应该传回PartialView,因为那是我最初加载到Modal中的内容?
public ActionResult PasswordReset(MemberViewModel vm)
{
MemberPasswordReset model = new MemberPasswordReset();
model.MemberId = vm.MemberId;
return PartialView("_PasswordReset", model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async System.Threading.Tasks.Task<ActionResult> PasswordReset(MemberPasswordReset model)
{
if (!ModelState.IsValid)
{
return PartialView("_PasswordReset", model);
}
ApplicationDbContext context = new ApplicationDbContext();
UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(context);
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(userStore);
String userId = User.Identity.GetUserId();
String hashedNewPassword = UserManager.PasswordHasher.HashPassword(model.Password);
ApplicationUser currentUser = await userStore.FindByIdAsync(userId);
await userStore.SetPasswordHashAsync(currentUser, hashedNewPassword);
await userStore.UpdateAsync(currentUser);
return RedirectToAction("MyAccount");
}
视图模型
public class MemberPasswordReset
{
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Confirm password doesn't match.")]
public string PasswordConfirm { get; set; }
public int MemberId { get; set; }
}
Bundle.config
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js"));
答案 0 :(得分:3)
您无法传回部分视图,因为它仅返回局部视图 - 而不是视图+模态内部加载的局部视图。所以你目前看到的是正确的。
您需要使用AJAX传回JSON响应,以便在模态的局部视图中进行验证。
如果模型状态不有效,则返回模型状态的键值对。这里有一个很好的开始示例:Example
一旦将其发送回您的视图,您可以使用jquery将模型错误(如果有)附加到验证摘要区域。
编辑:
请求的示例 -
<强>控制器强>
public class HomeController : BaseController
{
[HttpPost]
public ActionResult Edit(EditViewModel vm)
{
if(ModelState.IsValid)
{
//do stuff
return Json(new
{
status = "success"
//return values if needed
}
}
return Json(new
{
status = "failure",
formErrors = ModelState.Select(kvp => new { key = kvp.Key, errors = kvp.Value.Errors.Select(e => e.ErrorMessage)})});
}
}
}
查看强>
@using (Ajax.BeginForm("Edit", new AjaxOptions { OnSuccess = "onChangeSuccess"}))
{
//Modal header, body, footer
//Make sure your form fields actually contain their Razor validation fields
}
<强> JQuery的强>
function onChangeSuccess(data) {
if (data.status === "success") {
$("#modalcontent").modal('hide');
$("#message-area").html(data.view);
}
$.each(data.formErrors, function() {
$("[data-valmsg-for=" + this.key + "]").html(this.errors.join());
});
}