验证MVC中的复杂类

时间:2012-03-14 15:01:43

标签: model-view-controller asp.net-mvc-2

请考虑以下代码:

public class AccountNumber
{
    [AccountNumber] //This validator confirms the format of the account number 
    public string Value {get; set;}

    public int Format { get; set;}

    public string ToString() 
    {
        return Value + " is format " + Format;
    }
}

public class MyViewModel
{
     public MyViewModel()
     {
          SourceAccount = new AccountNumber();
          DestinationAccount= new AccountNumber();
     }

     [Required]
     AccountNumber SourceAccount {get; set;}

     AccountNumber DestinationAccount {get; set;} 
}

然后,在我的视图中:

@Html.EditorFor(model => model.SourceAccount.Value)
@Html.EditorFor(model => model.DestinationAccount.Value)

基本上,我想说用户必须输入源帐户,并且可选输入目标帐户。但是,如果他们确实输入了目标帐户,则必须符合某种格式。

上面代码的问题是SourceAccount上所需的验证器将始终返回有效,因为SourceAccount永远不为null。什么是实施我想要实现的目标的好方法?

请注意,在现实生活中,Value的设置器比显示的更复杂,因为它以规范格式重新格式化帐号。

编辑请注意,我们必须使用内置的MVC验证,因为这是项目当前正在使用的内容。

3 个答案:

答案 0 :(得分:2)

请参阅Extending the Model Binder for Enhanced Validation 这与内置的MVC验证完全兼容。

您当然可以使用自己的界面进行验证来自定义此解决方案。

答案 1 :(得分:1)

一种简单的方法可以是为SourceAccount和DestinationAccount数字添加简单的字符串属性,如下所示:

public class MyViewModel
{
    public MyViewModel()
    {
    }

    [Required]
    [AccountNumber]
    public string SourceAccountNumber { get; set; }

    [AccountNumber]
    public string DestinationAccountNumber { get; set; }

    public AccountNumber SourceAccount
    {
        get
        {
            return new AccountNumber
            {
                Value = SourceAccountNumber,
                Format = 0 // Set Format appropriately
            };
        }
    }

    public AccountNumber DestinationAccount
    {
        get
        {
            return new AccountNumber
            {
                Value = DestinationAccountNumber,
                Format = 0 // Set Format appropriately
            };
        }
    }
}

答案 2 :(得分:0)

也许您想尝试FluentValidation,它是数据注释属性的模型验证替代方案,它允许您添加更复杂的模型验证逻辑。

代码仍然非常简洁明了:

[Validator(typeof(PersonValidator))]
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int Age { get; set; }
}

public class PersonValidator : AbstractValidator<Person>
{
    public PersonValidator()
    {
        RuleFor(x => x.Id).NotNull();
        RuleFor(x => x.Name).Length(0, 10);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Age).InclusiveBetween(18, 60);
    }
}