新建一个.net core mvc专案後
预设每一个检视之所以都能套用版面配置页
主要是在於藉由.\Views_ViewStart.cshtml进行的全域预设版面配置设置
而预设专案微软验证脚本采用的是
.\Views\Shared_ValidationScriptsPartial.cshtml当中的jquery两个脚本
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
进行client验证机制。
预设版面配置页.\Views\Shared_Layout.cshtml,而针对脚本引入是没有特别去添加,因此需再各自检视中做引入。
@await RenderSectionAsync("Scripts", required: false)
在版面配置页面中,以非同步方式转译名为之区段的内容
public System.Threading.Tasks.Task<Microsoft.AspNetCore.Html.HtmlString> RenderSectionAsync (string name, bool required);
参数
name (String)
要呈现的区段。
required(Boolean)
指出 name 必须使用页面中的) (注册区段 @section 。
新增一控制器名ValidDemoController.cs跟相应Index检视
Index检视中去进行非同步引入验证脚本隶属的部分检视
@section scripts{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
在ViewModel中要进行验证相关的资料注解使用时
必须引用using System.ComponentModel.DataAnnotations;
各项注解用中括号包覆
预设各个衍生的验证资料注解都是继承自ValidationAttribute
#region 组件 System.ComponentModel.Annotations, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.ComponentModel.Annotations.dll
#endregion
#nullable enable
namespace System.ComponentModel.DataAnnotations
{
//
// 摘要:
// Serves as the base class for all validation attributes.
public abstract class ValidationAttribute : Attribute
{
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.ValidationAttribute
// class.
protected ValidationAttribute();
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.ValidationAttribute
// class by using the function that enables access to validation resources.
//
// 参数:
// errorMessageAccessor:
// The function that enables access to validation resources.
//
// 例外状况:
// T:System.ArgumentNullException:
// errorMessageAccessor is null.
protected ValidationAttribute(Func<string> errorMessageAccessor);
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.ValidationAttribute
// class by using the error message to associate with a validation control.
//
// 参数:
// errorMessage:
// The error message to associate with a validation control.
protected ValidationAttribute(string errorMessage);
//
// 摘要:
// Gets or sets an error message to associate with a validation control if validation
// fails.
//
// 传回:
// The error message that is associated with the validation control.
public string? ErrorMessage { get; set; }
//
// 摘要:
// Gets or sets the error message resource name to use in order to look up the System.ComponentModel.DataAnnotations.ValidationAttribute.ErrorMessageResourceType
// property value if validation fails.
//
// 传回:
// The error message resource that is associated with a validation control.
public string? ErrorMessageResourceName { get; set; }
//
// 摘要:
// Gets or sets the resource type to use for error-message lookup if validation
// fails.
//
// 传回:
// The type of error message that is associated with a validation control.
public Type? ErrorMessageResourceType { get; set; }
//
// 摘要:
// Gets a value that indicates whether the attribute requires validation context.
//
// 传回:
// true if the attribute requires validation context; otherwise, false.
public virtual bool RequiresValidationContext { get; }
//
// 摘要:
// Gets the localized validation error message.
//
// 传回:
// The localized validation error message.
protected string ErrorMessageString { get; }
//
// 摘要:
// Applies formatting to an error message, based on the data field where the error
// occurred.
//
// 参数:
// name:
// The name to include in the formatted message.
//
// 传回:
// An instance of the formatted error message.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is malformed.
public virtual string FormatErrorMessage(string name);
//
// 摘要:
// Checks whether the specified value is valid with respect to the current validation
// attribute.
//
// 参数:
// value:
// The value to validate.
//
// validationContext:
// The context information about the validation operation.
//
// 传回:
// An instance of the System.ComponentModel.DataAnnotations.ValidationResult class.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is malformed.
//
// T:System.ArgumentNullException:
// validationContext is null.
//
// T:System.NotImplementedException:
// System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(System.Object,System.ComponentModel.DataAnnotations.ValidationContext)
// has not been implemented by a derived class.
public ValidationResult? GetValidationResult(object? value, ValidationContext validationContext);
//
// 摘要:
// Determines whether the specified value of the object is valid.
//
// 参数:
// value:
// The value of the object to validate.
//
// 传回:
// true if the specified value is valid; otherwise, false.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is malformed.
//
// T:System.NotImplementedException:
// Neither overload of IsValid has been implemented by a derived class.
public virtual bool IsValid(object? value);
//
// 摘要:
// Validates the specified object.
//
// 参数:
// value:
// The object to validate.
//
// validationContext:
// The System.ComponentModel.DataAnnotations.ValidationContext object that describes
// the context where the validation checks are performed. This parameter cannot
// be null.
//
// 例外状况:
// T:System.ComponentModel.DataAnnotations.ValidationException:
// Validation failed.
//
// T:System.InvalidOperationException:
// The current attribute is malformed.
//
// T:System.NotImplementedException:
// System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(System.Object,System.ComponentModel.DataAnnotations.ValidationContext)
// has not been implemented by a derived class.
public void Validate(object? value, ValidationContext validationContext);
//
// 摘要:
// Validates the specified object.
//
// 参数:
// value:
// The value of the object to validate.
//
// name:
// The name to include in the error message.
//
// 例外状况:
// T:System.ComponentModel.DataAnnotations.ValidationException:
// value is not valid.
//
// T:System.InvalidOperationException:
// The current attribute is malformed.
public void Validate(object? value, string name);
//
// 摘要:
// Validates the specified value with respect to the current validation attribute.
//
// 参数:
// value:
// The value to validate.
//
// validationContext:
// The context information about the validation operation.
//
// 传回:
// An instance of the System.ComponentModel.DataAnnotations.ValidationResult class.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is malformed.
//
// T:System.NotImplementedException:
// System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(System.Object,System.ComponentModel.DataAnnotations.ValidationContext)
// has not been implemented by a derived class.
protected virtual ValidationResult? IsValid(object? value, ValidationContext validationContext);
}
}
Required
RequiredAttribute.cs
#region 组件 System.ComponentModel.Annotations, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.ComponentModel.Annotations.dll
#endregion
#nullable enable
namespace System.ComponentModel.DataAnnotations
{
//
// 摘要:
// Specifies that a data field value is required.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class RequiredAttribute : ValidationAttribute
{
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.RequiredAttribute
// class.
public RequiredAttribute();
//
// 摘要:
// Gets or sets a value that indicates whether an empty string is allowed.
//
// 传回:
// true if an empty string is allowed; otherwise, false. The default value is false.
public bool AllowEmptyStrings { get; set; }
//
// 摘要:
// Checks that the value of the required data field is not empty.
//
// 参数:
// value:
// The data field value to validate.
//
// 传回:
// true if validation is successful; otherwise, false.
//
// 例外状况:
// T:System.ComponentModel.DataAnnotations.ValidationException:
// The data field value was null.
public override bool IsValid(object? value);
}
}
Required中还可以特别去设置
AllowEmptyStrings的特性,该特性只有在Server-Side下才有作用。
代表是否远许一个空字串""(双引号包覆的空字串),空null。
在进行模型物件绑定输入框时,我们在输入框输入的空字串会被自动转为null因此AllowEmptyStrings=true会没有效果,不会去验证是否为空字串("")。
需要额外配置另一个特性DisplayFormat,去禁止将空字串("")转为null,也就是ConvertEmptyStringToNull属性设置为false。
新建好一个RequeredController.cs
using DotNet5App7.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class RequiredController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(RequiredViewModel model)
{
return View(model);
}
}
}
RequiredViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace DotNet5App7.Models
{
public class RequiredViewModel
{
[Display(Name="姓名")]
[Required(AllowEmptyStrings = true, ErrorMessage = "{0}不可为空!")]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string Name { get; set; }
[Display(Name ="年龄")]
[Required(ErrorMessage ="{0}不可为空!")]
public int Age { get; set; }
}
}
./Views/Required/Index.cshtml
@{
ViewData["Title"] = "非空验证";
}
@model RequiredViewModel
<form method="post">
<div>
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
<span asp-validation-for="Name"></span>
</div>
<div>
<label asp-for="Age"></label>
<input type="text" asp-for="Age" />
<span asp-validation-for="Age"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
原先设置运行效果
调整之後
**StringLength **
主要可以设置最小跟最大字元长度,若只设定一个参数时代表最大长度。
长度是以字元个数来算,一个中文字跟英文字母都算一个字元。
相关的属性还有MaxLength跟MinLength,当同时有使用到MaxLength跟MinLength属性时,也相当於使用StringLength属性。
MaxLength
指定最大允许输入字元数
MinLength
指定最少输入字元数
LengthViewModel.cs范本
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class LengthViewModel
{
[Display(Name = "用户名")]
//[MinLength(6, ErrorMessage = "{0}最小字元数是{1}。")]
//[MaxLength(10,ErrorMessage ="{0}最大字字元是{1}。")]
[StringLength(10, MinimumLength = 6, ErrorMessage = "{0}的最小字元数是{2},最大字元数是{1}。")]
[Required(ErrorMessage = "{0}不可为空。")]
public string UserName { get; set; }
}
}
LengthController.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class LengthController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
./Views/Length/Index.cshtml
@{
ViewData["Title"] = "字元长度验证";
}
@model LengthViewModel
<form method="post">
<div>
<label asp-for="UserName"></label>
<input type="text" asp-for="UserName" />
<span asp-validation-for="UserName"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
运行效果
RegularExpression
正规表示式匹配验证,比方email 、电话、年龄。
RegularExpressionAttribute.cs
#region 组件 System.ComponentModel.Annotations, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.ComponentModel.Annotations.dll
#endregion
#nullable enable
namespace System.ComponentModel.DataAnnotations
{
//
// 摘要:
// Specifies that a data field value in ASP.NET Dynamic Data must match the specified
// regular expression.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class RegularExpressionAttribute : ValidationAttribute
{
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.RegularExpressionAttribute
// class.
//
// 参数:
// pattern:
// The regular expression that is used to validate the data field value.
//
// 例外状况:
// T:System.ArgumentNullException:
// pattern is null.
public RegularExpressionAttribute(string pattern);
//
// 摘要:
// Gets or sets the amount of time in milliseconds to execute a single matching
// operation before the operation times out.
//
// 传回:
// The amount of time in milliseconds to execute a single matching operation.
public int MatchTimeoutInMilliseconds { get; set; }
//
// 摘要:
// Gets the regular expression pattern.
//
// 传回:
// The pattern to match.
public string Pattern { get; }
//
// 摘要:
// Formats the error message to display if the regular expression validation fails.
//
// 参数:
// name:
// The name of the field that caused the validation failure.
//
// 传回:
// The formatted error message.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is ill-formed.
//
// T:System.ArgumentException:
// The System.ComponentModel.DataAnnotations.RegularExpressionAttribute.Pattern
// is not a valid regular expression.
public override string FormatErrorMessage(string name);
//
// 摘要:
// Checks whether the value entered by the user matches the regular expression pattern.
//
// 参数:
// value:
// The data field value to validate.
//
// 传回:
// true if validation is successful; otherwise, false.
//
// 例外状况:
// T:System.ComponentModel.DataAnnotations.ValidationException:
// The data field value did not match the regular expression pattern.
//
// T:System.InvalidOperationException:
// The current attribute is ill-formed.
//
// T:System.ArgumentException:
// System.ComponentModel.DataAnnotations.RegularExpressionAttribute.Pattern is not
// a valid regular expression.
public override bool IsValid(object? value);
}
}
新建控制器和相应检视
RegularController.cs 就用预设回传Index,不动
./Views/Regular/Index.cshtml
@{
ViewData["Title"] = "正规表示式匹配验证";
}
@model RegularViewModel
<form>
<div>
<label asp-for="Age"></label>
<input type="text" asp-for="Age" />
<span asp-validation-for="Age"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
RegularViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class RegularViewModel
{
[Display(Name = "年龄")]
[RegularExpression("[1-9][0-9]", ErrorMessage = "{0}限定输入两位数字,开头不可用0。")]
public int Age { get; set; }
}
}
运行效果
Range
Range属性接受int , double的参数,可用於验证是否坐落特定数值范围。
该属性中可以用Type资料型态作为参数,用於接收传入参数为string的可用typeof()来进行型态转换。Range属性中最小值和最大值,也是包括在范围内的。
RangeAttribute.cs
#region 组件 System.ComponentModel.Annotations, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.ComponentModel.Annotations.dll
#endregion
#nullable enable
namespace System.ComponentModel.DataAnnotations
{
//
// 摘要:
// Specifies the numeric range constraints for the value of a data field.
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class RangeAttribute : ValidationAttribute
{
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.RangeAttribute
// class by using the specified minimum and maximum values.
//
// 参数:
// minimum:
// Specifies the minimum value allowed for the data field value.
//
// maximum:
// Specifies the maximum value allowed for the data field value.
public RangeAttribute(double minimum, double maximum);
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.RangeAttribute
// class by using the specified minimum and maximum values.
//
// 参数:
// minimum:
// Specifies the minimum value allowed for the data field value.
//
// maximum:
// Specifies the maximum value allowed for the data field value.
public RangeAttribute(int minimum, int maximum);
//
// 摘要:
// Initializes a new instance of the System.ComponentModel.DataAnnotations.RangeAttribute
// class by using the specified minimum and maximum values and the specific type.
//
// 参数:
// type:
// Specifies the type of the object to test.
//
// minimum:
// Specifies the minimum value allowed for the data field value.
//
// maximum:
// Specifies the maximum value allowed for the data field value.
//
// 例外状况:
// T:System.ArgumentNullException:
// type is null.
public RangeAttribute(Type type, string minimum, string maximum);
//
// 摘要:
// Gets or sets a value that determines whether any conversions of the value being
// validated to System.ComponentModel.DataAnnotations.RangeAttribute.OperandType
// as set by the type parameter of the System.ComponentModel.DataAnnotations.RangeAttribute.#ctor(System.Type,System.String,System.String)
// constructor use the invariant culture or the current culture.
//
// 传回:
// true to use the invariant culture for any conversions; false to use the culture
// that is current at the time of the validation.
public bool ConvertValueInInvariantCulture { get; set; }
//
// 摘要:
// Gets the maximum allowed field value.
//
// 传回:
// The maximum value that is allowed for the data field.
public object Maximum { get; }
//
// 摘要:
// Gets the minimum allowed field value.
//
// 传回:
// The minimum value that is allowed for the data field.
public object Minimum { get; }
//
// 摘要:
// Gets the type of the data field whose value must be validated.
//
// 传回:
// The type of the data field whose value must be validated.
public Type OperandType { get; }
//
// 摘要:
// Gets or sets a value that determines whether string values for System.ComponentModel.DataAnnotations.RangeAttribute.Minimum
// and System.ComponentModel.DataAnnotations.RangeAttribute.Maximum are parsed using
// the invariant culture rather than the current culture.
public bool ParseLimitsInInvariantCulture { get; set; }
//
// 摘要:
// Formats the error message that is displayed when range validation fails.
//
// 参数:
// name:
// The name of the field that caused the validation failure.
//
// 传回:
// The formatted error message.
//
// 例外状况:
// T:System.InvalidOperationException:
// The current attribute is ill-formed.
public override string FormatErrorMessage(string name);
//
// 摘要:
// Checks that the value of the data field is in the specified range.
//
// 参数:
// value:
// The data field value to validate.
//
// 传回:
// true if the specified value is in the range; otherwise, false.
//
// 例外状况:
// T:System.ComponentModel.DataAnnotations.ValidationException:
// The data field value was outside the allowed range.
//
// T:System.InvalidOperationException:
// The current attribute is ill-formed.
public override bool IsValid(object? value);
}
}
新建好RangeController.cs跟相应Index检视
Index.cshtml
@{
ViewData["Title"] = "范围验证";
}
@model RangeViewModel
<form>
<div>
<label asp-for="Price"></label>
<input type="text" asp-for="Price" />
<span asp-validation-for="Price"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
RangeViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class RangeViewModel
{
[Display(Name = "价格")]
//[Range(10.1,30.5,ErrorMessage ="{0}范围是{1}-{2}。")]
[Range(typeof(string), "10.1", "30.5", ErrorMessage = "{0}范围是{1}-{2}。")]
public double Price { get; set; }
}
}
运行效果
Compare
两次输入是否一致的验证
比方密码、验证密码
新建好CompareController.cs跟相应Index检视
Index.cshtml
(这里密码暂时用明码显示方式便於查看)
@{
ViewData["Title"] = "比较验证";
}
@model CompareViewModel
<form>
<div>
<label asp-for="Password"></label>
<input type="text" asp-for="Password" />
<span asp-validation-for="Password"></span>
</div>
<div>
<label asp-for="ConfirmPassword"></label>
<input type="text" asp-for="ConfirmPassword" />
<span asp-validation-for="ConfirmPassword"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
CompareViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class CompareViewModel
{
[Display(Name = "密码")]
[Required]
public string Password { get; set; }
[Display(Name = "确认密码")]
[Compare("Password", ErrorMessage = "{0}和密码不一致。")]
[Required]
public string ConfirmPassword { get; set; }
}
}
运行效果
Remote
可用来实践利用Server-Side的 call back函数执行client-side验证。
用法[Remote("动作方法名","隶属控制器名")],其隶属於Microsoft.AspNetCore.Mvc该命名空间。
RemoteAttribute.cs
#region 组件 Microsoft.AspNetCore.Mvc.ViewFeatures, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\5.0.0\ref\net5.0\Microsoft.AspNetCore.Mvc.ViewFeatures.dll
#endregion
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System;
namespace Microsoft.AspNetCore.Mvc
{
//
// 摘要:
// A Microsoft.AspNetCore.Mvc.RemoteAttributeBase for controllers which configures
// Unobtrusive validation to send an Ajax request to the web site. The invoked action
// should return JSON indicating whether the value is valid.
//
// 备注:
// Does no server-side validation of the final form submission.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class RemoteAttribute : RemoteAttributeBase
{
//
// 摘要:
// Initializes a new instance of the Microsoft.AspNetCore.Mvc.RemoteAttribute class.
//
// 参数:
// routeName:
// The route name used when generating the URL where client should send a validation
// request.
//
// 备注:
// Finds the routeName in any area of the application.
public RemoteAttribute(string routeName);
//
// 摘要:
// Initializes a new instance of the Microsoft.AspNetCore.Mvc.RemoteAttribute class.
//
// 参数:
// action:
// The action name used when generating the URL where client should send a validation
// request.
//
// controller:
// The controller name used when generating the URL where client should send a validation
// request.
//
// 备注:
// If either action or controller is null, uses the corresponding ambient value.
// Finds the controller in the current area.
public RemoteAttribute(string action, string controller);
//
// 摘要:
// Initializes a new instance of the Microsoft.AspNetCore.Mvc.RemoteAttribute class.
//
// 参数:
// action:
// The action name used when generating the URL where client should send a validation
// request.
//
// controller:
// The controller name used when generating the URL where client should send a validation
// request.
//
// areaName:
// The name of the area containing the controller.
//
// 备注:
// If either action or controller is null, uses the corresponding ambient value.
// If areaName is null, finds the controller in the root area. Use the Microsoft.AspNetCore.Mvc.RemoteAttribute.#ctor(System.String,System.String)
// overload find the controller in the current area. Or explicitly pass the current
// area's name as the areaName argument to this overload.
public RemoteAttribute(string action, string controller, string areaName);
//
// 摘要:
// Initializes a new instance of the Microsoft.AspNetCore.Mvc.RemoteAttribute class.
//
// 备注:
// Intended for subclasses that support URL generation with no route, action, or
// controller names.
protected RemoteAttribute();
//
// 摘要:
// Gets or sets the route name used when generating the URL where client should
// send a validation request.
protected string RouteName { get; set; }
protected override string GetUrl(ClientModelValidationContext context);
}
}
新建好RemoteController跟相应Index检视
RemoteController.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class RemoteController : Controller
{
public IActionResult Index()
{
return View();
}
/// <summary>
/// Call Back Function for Remote Validation
/// </summary>
/// <param name="name"></param>
/// <param name="age"></param>
/// <returns></returns>
public JsonResult CheckName(string name)
{
bool b = false;
if (name.Equals("Andy"))
{
b = true;
}
return Json(b);
}
}
}
Index.cshtml
@{
ViewData["Title"] = "Remote验证";
}
@model RemoteViewModel
<form>
<div>
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
<span asp-validation-for="Name"></span>
</div>
<div>
<label asp-for="Age"></label>
<input type="text" asp-for="Age" />
<span asp-validation-for="Age"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
@section scripts{
@{ await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
RemoteViewModel.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class RemoteViewModel
{
[Display(Name = "姓名")]
[Remote("CheckName", "Remote")]
public string Name { get; set; }
[Display(Name = "年龄")]
public int Age { get; set; }
}
}
这里可以观察运行结果
当输入一个随意的名称时会自动到server-side我们指定的call back函数做验证
当改为Andy时才消失警示(这里判断是大小写有差)
AdditionalFields属性於Remote下可以在多透过设置它来附加额外要验证的参数栏位。
使call back函数可以传进更多参数
微调後的RemoteViewModel.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class RemoteViewModel
{
[Display(Name = "姓名")]
[Remote("CheckName", "Remote", AdditionalFields = "Age", HttpMethod = "GET", ErrorMessage = "请输入正确的内容。")]
public string Name { get; set; }
[Display(Name = "年龄")]
public int Age { get; set; }
}
}
这里还可以透过HttpMethod设置要采用POST或GET(默认)
AdditionalFields 当有多个参数则可用逗号分隔。
微调後的RemoteController.cs
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class RemoteController : Controller
{
public IActionResult Index()
{
return View();
}
/// <summary>
/// Call Back Function for Remote Validation
/// </summary>
/// <param name="name"></param>
/// <param name="age"></param>
/// <returns></returns>
public JsonResult CheckName(string name,int age)
{
bool b = false;
if (name.Equals("Andy") && age > 30)
{
b = true;
}
return Json(b);
}
}
}
运行效果
DataType
用於设定使用显示/编辑模板呈现的模型物件属性转换的HTML控件类型。
以下这些enum选项都可以对应HTML呈现
新建好DataTypeController跟相应Index检视
Index.cshtml
@{
ViewData["Title"] = "DataType ";
}
@model DataTypeViewModel
<div>
<input asp-for="Title" />
</div>
DataTypeViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DataTypeViewModel
{
[DataType(DataType.DateTime)]
public string Title { get; set; }
}
}
运行效果
可以看到原生html input的type我没设置但已经被转为datetime-local的型态
换言之,往後我们可以直接在ViewModel的属性藉由DataType来抉择对应要呈现舍麽样子的html 。
那前面还有提到所谓可用於设定使用显示/编辑模板呈现
我们改套用编辑模板
这里我们修改多个属性的ViewModel
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DataTypeViewModel
{
[DataType(DataType.EmailAddress)]
public string Title { get; set; }
[DataType(DataType.Currency)]
public int Age { get; set; }
}
}
Index.cshml部分我们只需要一句就能取代很多行input tag绑定,套用编辑模板。
预设都在HtmlHelper底下很多种和Model相应的模板可用
这里用@Html.EditorForModel()
运行效果
EmailAddress
可将指定该特性的ViewModel属性转为type为email的input tag,可自动套用HTML5邮件格式的验证。
这里新增一个EmailAddressController和相应的Index检视
Index.cshtml
@{
ViewData["Title"] = "EmailAddress";
}
@model EmailAddressViewModel
<form>
<div>
<label asp-for="Email"></label>
<input asp-for="Email" />
<span asp-validation-for="Email"></span>
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
EmailAddressViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class EmailAddressViewModel
{
[Display(Name = "邮件")]
[EmailAddress()]
public string Email { get; set; }
}
}
运行效果
Display
前面一直用的主要就是用於做客制化label显示
其包含order属性,默认是采用升幂(序)由小到大排列,对於Display特性的Order属性,可对ViewModel中属性於编辑模板显示顺序进行排列(只限於编辑模板或显示模板)。
新建一个Display控制器和相应Index检视以及DisplayViewModel
Index检视
@{
ViewData["Title"] = "Display";
}
@model DisplayViewModel
<form>
<div>
@Html.EditorForModel()
@*<label asp-for="Id"></label>
<input type="text" asp-for="Id" />
<br />
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
<br />
<label asp-for="Sex"></label>
<input type="checkbox" asp-for="Sex" />*@
</div>
</form>
DisplayViewModel
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DisplayViewModel
{
[Display(Name="ID",Order =3)]
public int Id { get; set; }
[Display(Name="姓名",Order =1)]
public string Name { get; set; }
[Display(Name="性别",Order =2)]
public bool Sex { get; set; }
}
}
运行效果(预设bool会产生checkbox , ID为数字则呈现number选单)
默认情况下编辑模板会依照属性由上至下依序排列。
DisplayFormat
该属性可用於对模型物件中属性值进行格式化(Ex:货币、日期时间),藉由
DataFormatString ="格式类型"语法来指定要显示的格式。
新建DisplayFormatController跟相应的Index检视
还有对应ViewModel
DisplayFormatViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DisplayFormatViewModel
{
[Display(Name = "价格")]
[DisplayFormat(DataFormatString = "{0:C}")]
public double Price { get; set; }
}
}
DisplayFormatController.cs
using DotNet5App7.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class DisplayFormatController : Controller
{
public IActionResult Index()
{
DisplayFormatViewModel model = new DisplayFormatViewModel()
{
Price = 45.58
};
return View(model);
}
}
}
这里用[DisplayFormat(DataFormatString = "{0:C}")]去进行对应金钱格式设置,
该属性可以去判定隶属Server所在国家地理位置来做相应货币格式变换。
Index.cshtml
@{
ViewData["Title"] = "DisplayFormat";
}
@model DisplayFormatViewModel
<div>
<label asp-for="Price"></label>
<input type="text" asp-for="Price" />
</div>
当运行时会发现没有套用转为金钱格式的样子
原因在於我们目前处於编辑文字输入框的模式
要在对ViewModel中属性做额外ApplyFormatInEditMode为true的设置
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DisplayFormatViewModel
{
[Display(Name = "价格")]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
public double Price { get; set; }
}
}
再次运行即可
编辑模式在此也可用HtmlHelper提供方法搭配lambda语法来取代
@{
ViewData["Title"] = "DisplayFormat";
}
@model DisplayFormatViewModel
<div>
<label asp-for="Price"></label>
<input type="text" asp-for="Price" />
@Html.EditorFor(m=>m.Price)
</div>
DisplayFormat中的ConvertEmptyStringToNull默认为true,可将模型的属性值中若是空字串会被转为null。
这里扩充一个string属性Name
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DisplayFormatViewModel
{
[Display(Name = "价格")]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
public double Price { get; set; }
[DisplayFormat(ConvertEmptyStringToNull =false)]
public string Name { get; set; }
}
}
在检视我们调整成一个表单提交的画面
@{
ViewData["Title"] = "DisplayFormat";
}
@model DisplayFormatViewModel
<form method="post">
<div>
<label asp-for="Price"></label>
<input type="text" asp-for="Price" />
@Html.EditorFor(m => m.Price)
</div>
<div>
<label asp-for="Name"></label>
<input type="text" asp-for="Name" />
@Html.DisplayFor(m => m.Name)
</div>
<div>
<input type="submit" value="提交" />
</div>
</form>
DisplayFormatController中调整从View传进来模型接收的POST action method
using DotNet5App7.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Controllers
{
public class DisplayFormatController : Controller
{
public IActionResult Index()
{
DisplayFormatViewModel model = new DisplayFormatViewModel()
{
Price = 45.58
};
return View(model);
}
[HttpPost]
public IActionResult Index(DisplayFormatViewModel model)
{
return View(model);
}
}
}
运行效果
若这里不去对属性Name写[DisplayFormat(ConvertEmptyStringToNull =false)]
或者写[DisplayFormat(ConvertEmptyStringToNull =true)]
则Server-Side接收到会是null
在DisplayFormat中HtmlEncode属性可协助我们是否要开启或关闭要采用HTML来编码
默认为true启用的。
而NullDisplayText属性则是当属性值为null或空字串("")时,可设置预设为空要显示的默认字串内容。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace DotNet5App7.Models
{
public class DisplayFormatViewModel
{
[Display(Name = "价格")]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
public double Price { get; set; }
[DisplayFormat(NullDisplayText ="为空时的预设值")]
public string Name { get; set; }
}
}
本文同步发表至个人部落格(分两篇->因为铁人赛规划30天原先blog分两篇章)
.NET Core第29天_Model验证配置准备流程_各种验证资料注解使用方式_part1(Required,StringLength,MaxLength,MinLength,RegularExpression,Range,Compare)
https://coolmandiary.blogspot.com/2021/08/net-core29modelpart1.html
.NET Core第30天_Model验证配置准备流程_各种验证资料注解使用方式_part2(Remote,DataType,EmailAddress,Display,DisplayFormat验证)
https://coolmandiary.blogspot.com/2021/08/net-core30modelpart2remotedatatypeemail.html
>>: Day30 - 铁人付外挂部署与发行(三)- 贩售外挂
今天要来讲另一个方法,那就是VIEW方法,VIEW方法就是要建立一 个虚拟资料表,资料表本身没有储存...
团队目标的建立 提供对应的元素,催化IT团队与事业体相呼应的目标 身为产品经理,需要清楚知道公司目标...
基於昨日文章的说明, 我们已经建立了一个资料库协助我们暂存资料资料 但缺乏驱动负责拉取与上传资料的...
1.前言 前两篇使用到日常生活中使用率最高的通讯软件LINE Notify功能,不知道各位小夥伴是否...
昨天使用的是在有明确资讯时的例外处理,可以直接使用try catch抓出来,但有时在方法里需要传入资...