我有这个表单,其中有一个邮政编码字段,在我的 ViewModel 中它看起来像这样:

[RegularExpression(@"^\d{5}(-\d{4})?$")]
public string PostalCode { get; set; }

该正则表达式接受 5 位邮政编码,但现在我需要支持他们使用 8、4 或 6 位邮政编码的其他国家/地区。

我在数据库中有那些自定义正则表达式,但我不能以这种方式将非静态变量传递给属性:
[RegularExpression(MyCustomRegex)]
public string PostalCode { get; set; }

我能做什么?我尝试创建一个自定义属性,但在某些时候我需要传递一个非静态参数,这是不可能的。

我应该使用反射吗?有更干净的方法吗?

最佳答案

更好的方法可能是将属性与正则表达式分离。

public class PostalCodeAttribute : Attribute
{
    public string Country { get; set; }
}

public interface IPostalCodeModel
{
    string PostalCode { get; }
}

public class UsModel : IPostalCodeModel
{
    [PostalCode(Country = "en-US")]
    public string PostalCode { get; set; }
}

public class GbModel : IPostalCodeModel
{
    [PostalCode(Country = "en-GB")]
    public string PostalCode { get; set; }
}

验证器:
public class PostalCodeValidator
{
    private readonly IRegularExpressionService _regularExpressionService;

    public PostalCodeValidator(IRegularExpressionService regularExpressionService)
    {
        _regularExpressionService = regularExpressionService;
    }

    public bool IsValid(IPostalCodeModel model)
    {
        var postalCodeProperty = model.GetType().GetProperty("PostalCode");

        var attribute = postalCodeProperty.GetCustomAttribute(typeof(PostalCodeAttribute)) as PostalCodeAttribute;

        // Model doesn't implement PostalCodeAttribute
        if(attribute == null) return true;

        return ValidatePostalCode(_regularExpressionService, model, attribute.Country);
    }

    private static bool ValidatePostalCode(
        IRegularExpressionService regularExpressionService,
        IPostalCodeModel model,
        string country
    )
    {
        var regex = regularExpressionService.GetPostalCodeRegex(country);
        return Regex.IsMatch(model.PostalCode, regex);
    }
}

关于c# - 动态正则表达式属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18340587/

10-17 00:58