MVC 3模型验证问题 - 监督或设计

Jos*_*osh 21 .net c# validation asp.net-mvc asp.net-mvc-3

我遇到了一个场景,我需要知道哪个属性当前正在自定义中验证ValidationAttribute.我认为这在MVC 3中很容易,因为ValidationContext它被传递到IsValid方法中.

没有详细说明,这是基本的想法:

protected override ValidationResult IsValid(Object value, ValidationContext validationContext) {

   if (ShouldICareAboutYou(validationContext.MemberName))
   {
       //Do some stuff
   }

   //Return the results
}
Run Code Online (Sandbox Code Playgroud)

这似乎是完美的解决方案,事实上,当使用Validator.TryValidateObject一切工作精美地对我的自定义ValidationAttribute进行单元测试时!

然而...

在调用时TryUpdateModel,或TryValidateModel在我的控制器中,验证运行,但ValidationContext.MemberName为null.

哇啊?!?

我做了一点调查,果然,内部DataAnnotationsModelValidator就是代码......或缺乏代码.

public override IEnumerable<ModelValidationResult> Validate(object container) {
    // Per the WCF RIA Services team, instance can never be null (if you have
    // no parent, you pass yourself for the "instance" parameter).
    ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null); 
    context.DisplayName = Metadata.GetDisplayName();

    // Setting the MemberName here would be trivial!
    // However, philh told me not to. Something about
    // a guy named Josh who pushed him down on the playground
    // in middle school.

    //context.MemberName = Metadata.PropertyName; (Suck It, Josh!!!)

    ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context); 
    if (result != ValidationResult.Success) {
        yield return new ModelValidationResult { 
            Message = result.ErrorMessage
        };
    }
} 
Run Code Online (Sandbox Code Playgroud)

我意识到,如果没有对该属性应用,则DisplayName 可以是属性名称DisplayAttribute.不幸的是,我无法真正处理假设.我需要确切知道属性名称是什么.

那么这笔交易是什么?这是设计还是诚实的疏忽.如果它是一个疏忽,那么在MVC 4中修复它会很棒:)

免责声明:

加入上面的代码示例中的注释说着玩的.我不知道,也没见过Phil Haack.从我所知,他似乎是一个非常好的人.在中学推他下去会让我成为一个皇室冲洗!

tkb*_*dge 5

我遇到了同样的问题,决定将属性名称作为参数传递到属性构造函数中,然后将其存储在属性中。例如:

[MyValidationAttribute("MyProperty")]
public string MyProperty { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后在 MyValidationAttribute.cs 中:

public class MyValidationAttribute
{
    private string PropertyName;

    public MyValidationAttribute(string propertyName)
    {
        this.PropertyName = propertyName;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我必须输入财产名称两次,这有点烦人,但它解决了问题。


cou*_*ben 3

乔什,

令人沮丧,是的。

但是,出于您的目的,您可以创建自己的类DataAnnotationsModelValidator,继承自 ,重写该Validate()方法,并取消注释那行嘲笑您的代码。然后,在 Global.asax.cs 中,清除ModelValidatorProviders.Providers并添加您的类。

这不是最佳解决方案,但可以帮助您到达您需要去的地方。

  • 通过将此问题作为问题发布在 http://aspnet.codeplex.com/workitem/list/basic 上,您更有可能收到团队的来信。 (2认同)