0

我正在尝试NotAttribute为我的 MVC3 项目编写验证器属性。我想像这样使用它:

[Not("00000000-0000-0000-0000-000000000000", typeof(Guid), ErrorMessage = "You must select a valid id.")]
public Guid ObjectId { get; set; }

现在我不想将 a 绑定NotAttribute到 a Guid,但是该对象应该可以从字符串中解析;我想先找TryParse方法,再找Parse方法;如果两者都失败,并且类型还不是字符串,我想抛出一个错误。到目前为止,一切顺利,没有并发症。

我的课看起来像这样:

public class NotAttribute : ValidationAttribute, IClientValidatable
{
    public Type PropertyType { get; set; }
    public string NotEqualTo { get; private set; }
    public bool IgnoreWhitespace { get; set; }
    public bool CaseInsensitive { get; set; }

    public NotAttribute(string notEqualTo)
    {
        NotEqualTo = notEqualTo;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (PropertyType == null) PropertyType = typeof(string);
        if (PropertyType == typeof(string))
        {
            //this is the easy case.  We can compare easy enough
            var leftSide = value.ToStringOrEmpty();
            var rightSide = NotEqualTo ?? string.Empty;

            if (IgnoreWhitespace)
            {
                leftSide = leftSide.Trim();
                rightSide = rightSide.Trim();
            }

            if (CaseInsensitive)
            {
                leftSide = leftSide.ToUpperInvariant();
                rightSide = rightSide.ToUpperInvariant();
            }

            if (leftSide != rightSide) return null; // all is well
        }

        var tryParseMethod = PropertyType.GetMethod("TryParse",
            Reflection.BindingFlags.Static | Reflection.BindingFlags.Public, null,
            new Type[] {typeof(string), PropertyType.MakeByRefType()}, null);

        //This is where I get lost


        return base.IsValid(value, validationContext);
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        throw new NotImplementedException();
    }
}

我很确定我tryParseMethod会返回对理论上可以调用的对象方法的引用,但这是我遇到问题的地方。

我将如何调用它,传入在运行时确定的类型?这似乎是在为泛型实现而尖叫,但我不知道我可以在哪里注入它。此外,一旦我有了需要与“非”值进行比较的值,我需要在运行时以某种方式强制转换它,这也需要泛型。

我怎样才能使这项工作?我这样做完全错误吗?

4

1 回答 1

1

它是一个静态方法,因此您应该能够调用它而无需调用该类型的类的实例PropertyType(请参阅MSDN 页面)。因此,您可以调用Invoke.tryParseMethod

但是,该TryParse方法本身将需要该类型的一个类的实例PropertyType作为它的out参数,因此您需要使用System.Activator.CreateInstance()它。

所以,大概是这样的

var parsedObject = System.Activator.CreateInstance(PropertyType);
bool parseSuceeded = tryParseMethod.Invoke(null, new [] { value, parsedObject });

将完成这项工作。

于 2012-06-26T05:29:21.850 回答