ASP.NET Core 2.1不引人注目的Ajax验证不适用于部分视图窗体交换

时间:2018-11-15 19:23:44

标签: c# asp.net-core-mvc unobtrusive-validation asp.net-core-2.1

到目前为止,我已经花了几个小时来梳理Stackoverflow和其他站点,尝试每个人的解决方案都没有运气。我确定我错过了一些东西,但看不到。希望你能指出我的问题。

我在局部视图中有一个初始表单,该初始视图已呈现为一个父视图,其验证效果很好。通过Ajax替换提交表单后,我将在响应中返回带有新表单的登录或注册部分视图。提交不完整的表单并返回相同的局部视图时,第二个表单将不会显示模型验证错误。

在此先感谢您提供的一些技巧来结束这种精神错乱!

父视图部分

ARWorldTrackingConfiguration.supportedVideoFormats

正在工作的局部视图

<div class="row">
<div class="col-sm-8 col-sm-offset-2">
    <div class="panel panel-primary" id="formData">
        @await Html.PartialAsync("_UserNamePartial", new UserNameViewModel())
    </div>
</div>
</div>

初始验证控制器操作

<div class="panel-heading">
<h3 class="panel-title">Let's Start With Your E-mail Address</h3>
</div>
<div class="panel-body">
<div class="row">
    <div class="col-xs-12">
        <form asp-controller="Account" asp-action="IsAccountValid" data-ajax="true" data-ajax-method="POST"
              data-ajax-mode="replace" data-ajax-update="#formData">
            @Html.AntiForgeryToken()
            <div class="form-group">
                <label for="UserName">Your Email Address</label>
                <div class="input-group">
                    <input type="text" id="UserName" name="UserName" class="form-control" placeholder="Your email address" />
                    <div class="input-group-btn">
                        <button type="submit" id="btnGetStarted" class="btn btn-primary">Get Started</button>
                    </div>
                </div>
                <span asp-validation-for="UserName" class="text-danger"></span>
            </div>
        </form>
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    </div>
</div>
</div>

登录局部视图(验证错误显示不起作用)

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public IActionResult IsAccountValid(UserNameViewModel model)
    {
        if (!ModelState.IsValid)
            return PartialView("../Home/_UserNamePartial", model);

        AccountRepository accountRepository = new AccountRepository(ConnectionConfig.InshoraDev);
        AuthName match = accountRepository.GetAuthName(model.UserName);

        if (match != null)
        {
            ModelState.Clear();
            LoginViewModel loginModel = new LoginViewModel()
            {
                UserName = model.UserName
            };

            return PartialView("_UserLoginPartial", loginModel);
        }

        ModelState.Clear();
        SignUpViewModel signupModel = new SignUpViewModel()
        {
            UserName = model.UserName,
        };

        return PartialView("_UserSignUp", signupModel);
    }

LoginViewModel

@model Inshora.Models.Account.LoginViewModel

<div asp-validation-summary="ModelOnly" class="text-danger"></div>

<div class="panel-heading">
    <h3 class="panel-title">Log Into Your Account</h3>
</div>
<div class="panel-body">
    <div class="row">
        <div class="col-xs-12">
            <form id="login-form" asp-controller="Account" asp-action="Login" method="post" role="form" style="display: block;"
                  data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="formData" data-ajax-complete="AcctLib.Login.Events.onComplete">
                @Html.AntiForgeryToken()
                <div class="form-group">
                    <input type="text" name="UserName" id="UserName" tabindex="1" class="form-control" placeholder="Email Address" value="@Model.UserName">
                    <span asp-validation-for="UserName" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="password" name="Password" id="Password" tabindex="2" class="form-control" placeholder="Password">
                    <span asp-validation-for="Password" class="text-danger"></span>
                </div>
                <div class="form-group text-center">
                    <input type="checkbox" tabindex="3" class="" name="RememberMe" id="RememberMe">
                    <label for="RememberMe"> Remember Me</label>
                </div>
                <div class="form-group">
                    <div class="row">
                        <div class="col-sm-6 col-sm-offset-3">
                            <input type="submit" name="login-submit" id="login-submit" tabindex="4" class="form-control btn btn-primary" value="Log In">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="row">
                        <div class="col-lg-12">
                            <div class="text-center">
                                <a id="PasswordReset" asp-controller="Account" asp-action="PasswordReset" data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#formData" tabindex="5" class="inshora-forgot-password">Forgot Password?</a>
                            </div>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<script type="text/javascript">
    $(document).ready(function() {
        AcctLib.Login.Init();
    })
</script>

客户端初始化代码

public class LoginViewModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }

    [Required]
    public bool RememberMe { get; set; }
}

更新

我已将父页面(index.cshtml)更新为以下内容,但仍不显示消息。

AcctLib.Login.RebindForm = function() {
    $('form').each(function (i, f) {
        $form = $(f);
        $form.removeData('validator');
        $form.removeData('unobtrusiveValidation');
        $.validator.unobtrusive.parse($form);
    });
}

AcctLib.Login.Init = function () {
    AcctLib.Login.RebindForm();
    $('#UserName').focus();
}

3 个答案:

答案 0 :(得分:1)

问题是我没有使用过asp-for标签助手。这些助手负责生成非干扰式验证解析器所需的data- *属性。一旦我开始使用它们,它就会开始工作。谢谢所有尝试提供帮助的人。

更正的视图

<div class="panel-body">
    <div class="row">
        <div class="col-xs-12">
            <form id="login-form" asp-controller="Account" asp-action="Login" method="post" role="form"
                  data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#formData">
                @Html.AntiForgeryToken()
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="UserName"></label>
                    <input asp-for="UserName" class="form-control" placeholder="Email Address"/>
                    <span asp-validation-for="UserName" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Password"></label>
                    <input asp-for="Password" class="form-control" placeholder="Password"/>
                    <span asp-validation-for="Password" class="text-danger"></span>
                </div>
                <div class="form-group text-center">
                    <input asp-for="RememberMe" />
                    <label asp-for="RememberMe"> Remember Me</label>
                </div>
                <div class="form-group">
                    <div class="row">
                        <div class="col-sm-6 col-sm-offset-3">
                            <input type="submit" name="login-submit" id="login-submit" tabindex="4" class="form-control btn btn-primary" value="Log In">
                        </div>
                    </div>
                </div>
                <div class="form-group">
                    <div class="row">
                        <div class="col-lg-12">
                            <div class="text-center">
                                <a id="PasswordReset" asp-controller="Account" asp-action="PasswordReset" data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#formData" tabindex="5" class="inshora-forgot-password">Forgot Password?</a>
                            </div>
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

答案 1 :(得分:0)

if (!ModelState.IsValid)
   return PartialView("..\\Home\\_UserNamePartial", model);

非常确定这违反了路径

if(!ModelState.IsValid)
   return PartialView("../Home/_UserNamePartial", model);

答案 2 :(得分:-1)

剪切renderPartial链接并粘贴到@script部分之前,如下所示:

@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }

@section Scripts
{

}