模型-视图控制器-C#MVC使用多个具有OR条件的atrribute
本文关键字:OR 条件 atrribute 视图 控制器 -C#MVC 模型 | 更新日期: 2023-09-27 18:00:19
我的目标是创建一个经过验证的IP地址字段,该字段将根据IP地址常规快递或动态DNS地址进行验证。因此,基本上,如果用户输入有效的IP地址或有效的动态DNS地址,客户端将允许其通过。我发现一些文章展示了如何创建自定义字段以及如何在数据字段上创建多个属性,但没有介绍如何将它们作为OR条件运行。
以下是我的自定义IP和域名属性代码:
public class IPAddressAttribute : RegularExpressionAttribute
{
public IPAddressAttribute()
: base(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
{ }
}
public class DomainNameAttribute : RegularExpressionAttribute
{
public DomainNameAttribute()
: base(@"^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9'-]*[a-zA-Z0-9])'.)*([A-Za-z]|[A-Za-z][A-Za-z0-9'-]*[A-Za-z0-9])$")
{ }
}
这是我在这个领域的代码:
[Required(ErrorMessage="Wan IP is required")]
[DisplayName("Wan IP")]
[IPAddress(ErrorMessage="Enter a valid IP")]
[DomainName(ErrorMessage="Enter a valid Domain Name")]
public virtual string wan_ip { get; set; }
此代码当前检查这两个属性。当我输入一个有效的IP地址时,它会回来说我需要输入一个合法的域名,这是可以理解的,因为它试图验证这两个属性。因为它们是相互排斥的,所以它们永远不会同时满足。
如有任何建议,我们将不胜感激!
谢谢!
Matthew
我敢肯定你必须将它们合并到一个单独的属性中,类似于
[域名或IP地址]
并在属性中处理OR逻辑。
或者,您可以查看自定义模型验证器
您可以创建一个自定义验证属性,并使用其中现有的两个属性。MSDN上有一篇关于创建自定义属性的文章。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
sealed public class CustomAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
IPAddressAttribute a1 = new IPAddressAttribute();
DomainNameAttribute a2 = new DomainNameAttribute();
return a1.IsValid(value) || a2.IsValid(value);
}
}
使用Jason建议的策略,您还可以创建一个更通用的属性来处理"Or"逻辑。我发现最好的方法是接收这两个属性的Type,然后在内部激活它们(因为属性上有很强的参数约束)。
用法:
[OneOfAttribute(typeof(IPAddressAttribute), typeof(DomainNameAttribute), ...)]
实施:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class OneOfAttribute : ValidationAttribute
{
public ValidationAttribute[] Validators { get; set; }
public OneOfAttribute(params Type[] validatorTypes)
{
Validators = validatorTypes.Select(Activator.CreateInstance)
.OfType<ValidationAttribute>()
.ToArray();
// just to make sure this was correctly invoked
if (validatorTypes.Length != Validators.Length)
{
throw new ArgumentException("Invalid validation attribute type");
}
}
public override bool IsValid(object value)
{
return Validators.Any(v => v.IsValid(value));
}
}
使用此策略还可以使其更加灵活,添加一个参数来指定将在IsValid方法上使用的逻辑运算(OR、AND等)的类型。