部分视图验证的MVC 5与Bootstrap Modal不起作用?

时间:2016-09-16 14:09:26

标签: jquery asp.net-mvc twitter-bootstrap asp.net-mvc-5

我现在已经开始工作了几天,并且不能像我期望的那样让它工作。 我看了很多例子,但我必须误解一些事情。

我所拥有的是一个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">&times;</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>&nbsp;&nbsp;

                    <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"));

1 个答案:

答案 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());
    });
}