【问题标题】:How to make this ASP.NET Core Model Validation work on client-side?如何让这个 ASP.NET Core 模型验证在客户端工作?
【发布时间】:2018-02-11 00:16:47
【问题描述】:

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

场景

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

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

注意:所有的css和javascripts都是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>

【问题讨论】:

  • 你在局部视图中使用@section scripts { }之类的东西吗?
  • @Ali 感谢您的帮助。不,我没有使用@section scripts { }
  • 您能否更新帖子以显示您将脚本用于客户端验证的位置?
  • @Ali 我没有将脚本放在任何地方。当使用默认的ASP.NET Core Web Application 模板创建网络应用程序时,我所拥有的只是VS2017_layout.cshtml 文件(如上所示)中放置和配置的内容。

标签: asp.net-core model-validation


【解决方案1】:

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

现在要做的第一件事是向您的视图模型添加验证属性,例如[Required]

主视图中,在&lt;script&gt;之前添加@{ 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);
}

【讨论】:

  • 您的建议奏效了(感谢您对我的帮助)。请注意,如上面的模型所示,float? 可以为空,因此不是必填字段。所以我不必使用[Required] DataAnnotation。但关键是您建议在&lt;script&gt; 之前添加@{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } before &lt;script&gt;,最重要的是上面Ajax 代码的最后两行。为了其他读者的利益,您可能需要删除上面回复中的[Required] 部分,因为所提出的问题不需要这样做。
猜你喜欢
  • 2023-04-01
  • 1970-01-01
  • 2021-09-24
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多