新建一個.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