如何使这个 ASP.NET 核心模型验证在客户端工作?

How to make this ASP.NET Core Model Validation work on client-side?

在我的 ASP.NET Core 1.1.1 应用程序中,以下 Model Validation 不起作用。我认为这个问题与我没有在下面的主视图中正确添加验证脚本有关。

场景

  1. 我在主视图上单击了一个调用 partial view 的按钮。
  2. 我在局部视图中输入了所有正确的值并提交了表单(在局部视图中),表单 successfully 被提交并且所有值都正确输入到 SQL 服务器数据库中。
  3. 然后我 intentionallyprice(即 nullable type float)的输入框中输入一个字符串,比如 abc 并提交表格。客户端错误甚至没有显示(javascript 在我的 Chrome 浏览器上启用)。因此,表单被提交到服务器,其中 ModeState.IsValid 正如预期的那样,在 POST 操作方法中是 false

问题:为什么上面的客户端验证(如步骤 3 所示)不起作用,我们如何才能让它起作用?

注意:所有的css和javascript都是VS2017在创建项目时默认添加配置的。所以我认为脚本都在那里,我可能没有在视图上正确调用它们 - 但这只是一个假设。

MyViewModel

public class MyViewModel
{
    public int FY { get; set; } 
    public byte OrderType { get; set; }
    public float? Price { get; set; } 
    ....
}

主视图

@model MyProj.Models.MainViewModel

...
<div>
  <button type="submit" name="submit"...>GO</button>
</div
@section scripts
{
  <script>
    $(document).ready(function () {
     ....
     $('.tab-content').on('click', '.BtnGO', function (event) {
    ....    
    $.ajax({
        url: '@Url.Action("SU_AddCustOrder", "MyContr")',
        data: { ....},
        contentType: 'application/json',
        dataType: 'html',
        type: 'GET',
        cache: false,
        success: function (data) {
            if (BtnVal == 'AddOrderBtnGo')
                $('#menuAP').html(data);
            else if ....
        error: function (....){
              alert(...);
        }
    });
});

MyContrController:

[HttpGet]
public IActionResult AddCustOrder(int Order_id)
{
 ....
 return PartialView("~/Views/PartialsV/MyPartialView.cshtml", myVM);
 ....
}

[HttpPost]
public IActionResult AddCustOrder(MyViewModel model)
{
 ....
 if(ModelState.IsValid)
 {
   ....
 }
 ....
}

局部视图

....
<div class="form-group">
    <label asp-for="Price"></label>
    <div class="col-md-10">
        <input asp-for="Price" class="form-control"></input>
        <span asp-validation-for="Price" class="text-danger"></span>
    </div>
</div>
....
<button type="submit" name="submit"...>Add Order</button>

更新

_layout.cshtm 文件

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Test</title>

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
    @RenderSection("styles", required:false)
</head>
<body>
    <header>
        <div class="container navbar navbar-inverse navbar-fixed-top text-center">
        </div>
        <div class="container nav nav-pills" style="margin-top:4px;background-color:cornsilk;">
            @await Component.InvokeAsync("Welcome")
        </div>
    </header>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer class="text-center">
            <a asp-controller="Misc" asp-action="AccessibilityStatement" class="text-center text-muted">Accessibility Statement</a>
        </footer>
    </div>

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("scripts", required: false)
    @RenderSection("css", required:false)
</body>
</html>

我明白了。如果打开 Views 文件夹中的 Shared 文件夹,您会发现一个名为 _ValidationScriptsPartial.cshtml 的文件,其中包含验证脚本。

现在要做的第一件事就是添加验证属性例如[Required]到你的视图模型。

主视图 <script> 之前添加 @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }

$('#menuAP').html(data);这一行添加局部视图的html后,找到窗体并调用$.validator.unobtrusive.parse(),如下所示

if (BtnVal == 'AddOrderBtnGo') {
   $('#menuAP').html(data);
   var $form = $('#menuAP').find('#your-form-id-here');
   $.validator.unobtrusive.parse($form);
}