如何使这个 ASP.NET 核心模型验证在客户端工作?
How to make this ASP.NET Core Model Validation work on client-side?
在我的 ASP.NET Core 1.1.1
应用程序中,以下 Model Validation 不起作用。我认为这个问题与我没有在下面的主视图中正确添加验证脚本有关。
场景:
- 我在主视图上单击了一个调用
partial view
的按钮。
- 我在局部视图中输入了所有正确的值并提交了表单(在局部视图中),表单
successfully
被提交并且所有值都正确输入到 SQL 服务器数据库中。
- 然后我
intentionally
在 price
(即 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);
}
在我的 ASP.NET Core 1.1.1
应用程序中,以下 Model Validation 不起作用。我认为这个问题与我没有在下面的主视图中正确添加验证脚本有关。
场景:
- 我在主视图上单击了一个调用
partial view
的按钮。 - 我在局部视图中输入了所有正确的值并提交了表单(在局部视图中),表单
successfully
被提交并且所有值都正确输入到 SQL 服务器数据库中。 - 然后我
intentionally
在price
(即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);
}