繁体   English   中英

MVC 3如何验证整个ViewModel?

[英]MVC 3 how do I validate entire ViewModel?

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

假设示例1

在MVC 3中使用MVVM模式。我的(假设的)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,否则显示验证消息“样本总数不够高”

等...等...

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

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

我将扩展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; }

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM