MVC 3如何验证整个ViewModel?

时间:2013-10-02 20:34:23

标签: c# asp.net-mvc-3 validation mvvm model

我正在尝试验证模型,其中规则并不总是相同,并且取决于模型中的其他属性。这样做的最佳方法是什么?示例如下:

假设示例1

将MVVM模式与MVC一起使用3.我的(假设的)ViewModel如下所示:

public string OrderType { get; set; }
public string Requestor { get; set; }
public int NumberOfPeanuts { get; set; }
public int NumberOfJellyBeans { get; set; }
public int NumberOfAlmonds { get; set; }

我的观点基本上是这样的:

 @Html.EditorFor(model => model.OrderType ) 
 @Html.EditorFor(model => model.Requestor ) 
 @Html.EditorFor(model => model.NumberOfPeanuts ) 
 @Html.EditorFor(model => model.NumberOfJellyBeans ) 
 @Html.EditorFor(model => model.NumberOfAlmonds )

我如何实现将为以下规则返回“Html.ValidationMessageFor”结果的验证:

如果OrderType =“Peanuts”,那么NumberOfPeanuts必须大于0,而NumberOfJellyBeans和NumberOfAlmonds必须为null或0,否则显示“这是一个只有花生的订单”

如果OrderType =“Sample”,则NumberOfPeanuts + NumberOfJellyBeans + NumberOfAlmonds必须小于30,否则显示验证消息“样本总量不够高”

等等...等等......

2 个答案:

答案 0 :(得分:0)

您可以使用自己的自定义验证属性扩展ValidationAttribute

public class CustomAttribute : ValidationAttribute
{    
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // validation logic
    }
}

答案 1 :(得分:0)

我将扩展Sam的答案,使用多个模型属性来验证:

public class PeanutOrderAttribute : ValidationAttribute, IClientValidatable
{
    private readonly string _peanutsProperty;
    private readonly string _orderTypeProperty;

    public PeanutOrderAttribute(string peanutsPropertyName, string orderTypePropertyName)
    {
        _peanutsProperty = peanutsPropertyName;
        _orderTypeProperty = orderTypePropertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // get target property and value
        var peanutInfo = validationContext.ObjectType.GetProperty(this._peanutsProperty);
        var peanutValue = peanutInfo.GetValue(validationContext.ObjectInstance, null);

        // get compare property and value
        var ordertypeInfo = validationContext.ObjectType.GetProperty(this._orderTypeProperty);
        var ordertypeValue = ordertypeInfo.GetValue(validationContext.ObjectInstance, null);

        // if validation does not pass
        if (ordertypeValue == "Peanuts" && peanutValue < 1){
             return new ValidationResult("Error Message");
        }

        // else return success
        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessageString,
            ValidationType = "PeanutOrder"
        };

        rule.ValidationParameters["peanuts"] = this._peanutsProperty;
        rule.ValidationParameters["ordertype"] = this._orderTypeProperty;

        yield return rule;
    }
}

然后将验证标记放在适当的模型属性上:

[PeanutOrder("Peanuts", "OrderType")]
public int Peanuts{ get; set; }

public string OrderType { get; set; }

希望这有帮助!