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

本文关键字:模型 验证 控制器 | 更新日期: 2023-09-27 18:13:50

我想利用的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);
}

传入一个实现字典的实例

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不像我期望的那样工作。数据参数应该是模型属性的字符串对象表示吗?验证结果看起来好像只是没有赋值,而不是不正确。

希望有人能看到我在这里想要实现什么…

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

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

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; }
}

有了这样的属性,你就可以在任何其他字段上使用该逻辑。