c# - ASP.NET Core 2.1 不引人注目的 Ajax 验证不适用于部分 View 表单交换

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

我花了几个小时梳理 Stackoverflow 和其他网站,尝试每个人的解决方案,但到目前为止都没有成功。我确定我错过了什么,但我看不到。希望您能指点我解决问题。

我在部分 View 中有一个初始表单,该表单呈现到父 View 中,其验证工作正常。通过 Ajax 替换提交表单后,我会在响应中返回带有新表单的登录或注册部分 View 。当提交不完整的表单并返回相同的部分 View 时,第二个表单将不会显示模型验证错误。

提前感谢您提供的任何提示来结束这种疯狂!

父 View 部分

<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>

工作渲染局部 View

<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>

初始验证 Controller 操作

    [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);
    }

登录部分 View (验证错误显示不起作用)

@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>

登录 View 模型

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

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

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

客户端初始化代码

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

更新

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

<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>

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

最佳答案

问题是我没有使用 asp-for 标签助手。这些助手负责生成不显眼的验证解析器所需的 data-* 属性。一旦我开始使用它们,它就开始工作了。感谢所有试图提供帮助的人。

更正 View

<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>

关于c# - ASP.NET Core 2.1 不引人注目的 Ajax 验证不适用于部分 View 表单交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53326598/

相关文章:

c# - 从 2.1 迁移到 3.1 .Net Core,Microsoft.AspNetCore.App 的替代品是什么?

c# - 不再需要 stringbuilder 了吗?

c# - 来自 ARM 的访问 token 在收到时已过期

c# - 如何删除字符串中的任何 utf8mb4 字符

asp.net-core - .NET Core 中的分布式缓存 (Redis)

jquery - 使用 jquery.validate.unobtrusive 验证后调用脚本

c# - MVC3 阻止客户端设置模型值

c# - MVC 6 中的 JsonResult 未收到任何响应

jquery - 将 jQuery 验证器规则添加到 ASP 中动态创建的元素

javascript - 重新解析从部分 View 创建的表单后,jQuery 提交事件未触发