如何在控制器之外重用模型验证?

时间:2016-10-19 11:49:17

标签: c# validation model-view-controller

我想要利用的MVC模型验证的特定功能是在将数据分配给对象实例的属性之前验证数据。

例如,如果我有班级:

public class Test
{
    [Required(ErrorMessage="Id is required")]
    public int Id { get; set; }

    [Required(ErrorMessage="Name is required")]
    [RegularExpression(Constants.SomeRegex,  ErrorMessage = "Please enter a valid value for Name")]
    public int Name { get; set; }
}

我希望能够验证在尝试创建实例之前至少可以分配分配给“Id”的值。在这种情况下,这意味着可以赋值给一个整数 - 因此值“ABC”将无法验证。

当然我无法为Id创建一个值为“ABC”的Test实例,它不能分配给Int32。

MVC控制器实现此功能 - 在创建模型类的实例之前,将报告错误。

为此,我到目前为止尝试使用System.CompondentModel.DataAnnotations.Validator

public bool IsValid(IDictionary<object, object> data, out OfferConfig offerConfig)
{
    offerConfig = new OfferConfig();

    var context = new ValidationContext(offerConfig, data);
    var results = new List<ValidationResult>();

    return Validator.TryValidateObject(offerConfig, context, results, true);
}

传递实现IDictionary的实例

var dict = new Dictionary<object, object>
{
    {"Id", dataTable.Rows[i][0].ToString()},
    {"Name", dataTable.Rows[i][1].ToString()}
} 

像这样:

Test testInstance;

bool isValid = IsValid(dict, out testInstance);

但也许Validator不能像我期望的那样工作。数据参数是否应该是模型属性的字符串对象表示?验证结果显示为好像没有分配值而不是错误。

希望有人能看到我在这里想要实现的目标......

1 个答案:

答案 0 :(得分:0)

只需创建新的验证属性,您将在其中放置验证逻辑。像这样:

public class StringIdLengthRangeAttribute : ValidationAttribute
{
    public int Minimum { get; set; }
    public int Maximum { get; set; }

    public StringLengthRangeAttribute()
    {
       this.Minimum = 0;
       this.Maximum = int.MaxValue;
    }

    public override bool IsValid(object value)
    {
        string strValue = value as string;
        if (!string.IsNullOrEmpty(strValue))
        {
            int len = strValue.Length;
            return len >= this.Minimum && len <= this.Maximum;
        }
        return true;
    }
}

这是长度的示例验证 - 用验证逻辑替换它。 而你的班级:

public class Test
{
   [Required]
   [StringIdLengthRange(Minimum = 10, Maximum = 20)]
   public string Id { get; set; }
}

使用此属性,您可以在任何其他字段上使用该逻辑。