如何使用来自模型属性的动态模式创建regularExpressionAttribute

6
public class City
{
   [DynamicReqularExpressionAttribute(PatternProperty = "RegEx")]
   public string Zip {get; set;}
   public string RegEx { get; set;} 
}

我希望创建一个属性,其中模式来自另一个属性,而不是像原始的RegularExpressionAttribute那样静态声明。
任何想法都将不胜感激 - 谢谢。
2个回答

7

以下内容应该符合要求:

public class DynamicRegularExpressionAttribute : ValidationAttribute
{
    public string PatternProperty { get; set; }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        PropertyInfo property = validationContext.ObjectType.GetProperty(PatternProperty);
        if (property == null)
        {
            return new ValidationResult(string.Format("{0} is unknown property", PatternProperty));
        }
        var pattern = property.GetValue(validationContext.ObjectInstance, null) as string;
        if (string.IsNullOrEmpty(pattern))
        {
            return new ValidationResult(string.Format("{0} must be a valid string regex", PatternProperty));
        }

        var str = value as string;
        if (string.IsNullOrEmpty(str))
        {
            // We consider that an empty string is valid for this property
            // Decorate with [Required] if this is not the case
            return null;
        }

        var match = Regex.Match(str, pattern);
        if (!match.Success)
        {
            return new ValidationResult(this.FormatErrorMessage(validationContext.DisplayName));
        }

        return null;
    }
}

接下来:

模型:

public class City
{
    [DynamicRegularExpression(PatternProperty = "RegEx")]
    public string Zip { get; set; }
    public string RegEx { get; set; }
}

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var city = new City
        {
            RegEx = "[0-9]{5}"
        };
        return View(city);
    }

    [HttpPost]
    public ActionResult Index(City city)
    {
        return View(city);
    }
}

查看:

@model City
@using (Html.BeginForm())
{
    @Html.HiddenFor(x => x.RegEx)

    @Html.LabelFor(x => x.Zip)
    @Html.EditorFor(x => x.Zip)
    @Html.ValidationMessageFor(x => x.Zip)

    <input type="submit" value="OK" />
}

嗨Darin,非常好的解决方案,但它在客户端上不起作用,无法进行非侵入式验证。Philipp - Philipp Troxler
1
@Philipp Troxler,这很正常。我没有实现它作为客户端验证不是你问题的一部分。要实现这个功能,您可以使此属性实现IClientValidatable并注册自定义jQuery适配器。以下是一个示例,可能会让您走上正确的道路:https://dev59.com/Rm445IYBdhLWcg3wl7bW#4784986 - Darin Dimitrov
太好了,至少我没有遇到EntityValidationException异常,现在我有一些希望了 :) 我得到的是 PropertyInfo property = validationContext.ObjectType.GetProperty(PatternProperty);返回null,所以现在异常是“MyExpression”未知属性。已经花了2天时间找到这个问题,你能帮我吗?谢谢 :) - SMI

0
重写接受ValidationContext参数的Validate方法,使用ValidationContext从相关属性中获取正则表达式字符串并应用该正则表达式,返回匹配的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接