2016-08-23 194 views

回答

0

要通过注释定义自定义验证程序,您可以定义自己的类,该类自ValidationAttribute派生并覆盖IsValid方法。没有必要明确注册这个类。

在此示例中,自定义验证属性用于仅接受奇数作为有效值。

public class MyModel 
{ 
    [OddNumber] 
    public int Number { get; set; } 
} 

public class OddNumberAttribute : ValidationAttribute 
{ 
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     try 
     { 
      var number = (int) value; 
      if (number % 2 == 1) 
       return ValidationResult.Success; 
      else 
       return new ValidationResult("Only odd numbers are valid."); 
     } 
     catch (Exception) 
     { 
      return new ValidationResult("Not a number."); 
     }    
    } 
} 

第二种方法是Model类实现IValidatableObject。这是特别有用的,如果验证需要访问模型类的多个成员。这里是奇数验证的第二个版本:

public class MyModel : IValidatableObject 
{ 
    public int Number { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (Number % 2 == 0) 
      yield return new ValidationResult(
       "Only odd numbers are valid.", 
       new [] {"Number"}); 
    } 
} 

您可以找到有关https://docs.asp.net/en/latest/mvc/models/validation.html#custom-validation定制验证的更多信息。

+2

谢谢您的回复。但我想同时使用服务器端和客户端验证以及关注逻辑的分离,为此,我创建了 - public class RequiredIfValidationAttribute:ValidationAttribute {// ...}和public class RequiredIfValidationAdaptor: AttributeAdapterBase {// ...},但我不知道如何在** ASP.Net Core MVC **中注册该适配器。在MVC 5中,我使用了** DataAnnotationsModelValidatorProvider.RegisterAdapter(...)**。你有什么想法吗? –

6

在我看来,ASP.NET Core MVC不再支持DataAnnotationsModelValidatorProvider.RegisterAdapter了。我发现的解决方案如下:

假设我想为RequiredAttribute的验证更改为我自己的验证适配器(MyRequiredAttributeAdaptor),更改的EmailAddressAttribute默认的错误消息,并更改本地化错误消息来源为“CompareAttribute”来我自己的信息。

1 - 创建一个自定义ValidationAttributeAdapterProvider

using Microsoft.AspNetCore.Mvc.DataAnnotations; 
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; 
using Microsoft.Extensions.Localization; 
using Rima.AttributeAdaptors; 
using System.ComponentModel.DataAnnotations; 


namespace Rima.Validation 
{ 
    public class CustomValidationAttributeAdapterProvider 
     : ValidationAttributeAdapterProvider, IValidationAttributeAdapterProvider 
    { 
     public CustomValidationAttributeAdapterProvider() 
     { 
     } 

     IAttributeAdapter IValidationAttributeAdapterProvider.GetAttributeAdapter(
      ValidationAttribute attribute, 
      IStringLocalizer stringLocalizer) 
     { 
      IAttributeAdapter adapter; 
      if (attribute is RequiredAttribute) 
      { 
       adapter = new MyRequiredAttributeAdaptor((RequiredAttribute) attribute, stringLocalizer); 
      } 
      else if (attribute is EmailAddressAttribute) 
      { 
       attribute.ErrorMessage = "Invalid Email Address."; 
       adapter = base.GetAttributeAdapter(attribute, stringLocalizer); 
      } 
      else if (attribute is CompareAttribute) 
      { 
       attribute.ErrorMessageResourceName = "InvalidCompare"; 
       attribute.ErrorMessageResourceType = typeof(Resources.ValidationMessages); 
       var theNewattribute = attribute as CompareAttribute; 
       adapter = new CompareAttributeAdapter(theNewattribute, stringLocalizer); 
      } 
      else 
      { 
       adapter = base.GetAttributeAdapter(attribute, stringLocalizer); 
      } 

      return adapter; 
     } 
    } 
} 

2-添加CustomValidationAttributeAdapterProvider启动:

以下行添加到public void ConfigureServices(IServiceCollection services)在Startup.cs:

services.AddSingleton <IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>(); 

这里是MyRequiredAttributeAdaptor适配器:

using System; 
using System.ComponentModel.DataAnnotations; 
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; 
using Microsoft.Extensions.Localization; 
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal; 
namespace Rima.AttributeAdaptors 
{ 
    public class MyRequiredAttributeAdaptor : AttributeAdapterBase<RequiredAttribute> 
    { 
     public MyRequiredAttributeAdaptor(RequiredAttribute attribute, IStringLocalizer stringLocalizer) 
      : base(attribute, stringLocalizer) 
     { 
     } 

     public override void AddValidation(ClientModelValidationContext context) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException(nameof(context)); 
      } 

      MergeAttribute(context.Attributes, "data-val", "true"); 
      MergeAttribute(context.Attributes, "data-val-required", GetErrorMessage(context)); 
     } 

     /// <inheritdoc /> 
     public override string GetErrorMessage(ModelValidationContextBase validationContext) 
     { 
      if (validationContext == null) 
      { 
       throw new ArgumentNullException(nameof(validationContext)); 
      } 

      return GetErrorMessage(validationContext.ModelMetadata, validationContext.ModelMetadata.GetDisplayName()); 
     } 
    } 
} 

参考文献:

1-请参阅Microsoft的例子:熵项目:这是.NET的核心功能不同势很大的样品。在这个问题:看MinLengthSixAttribute实施Mvc.LocalizationSample.Web样品中:

https://github.com/aspnet/Entropy/tree/dev/samples/Mvc.LocalizationSample.Web

2 - 为了看看属性适配器作品看asp.Microsoft.AspNetCore.Mvc。github上的DataAnnotations:

https://github.com/aspnet/Mvc/tree/dev/src/Microsoft.AspNetCore.Mvc.DataAnnotations