.Net MVC2 如何在使用自定义 ValidationAttribute 时向 ModelState 添加错误

发布于 2024-09-08 00:15:56 字数 1860 浏览 7 评论 0原文

我有以下 ValidationAttribute 类,

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class DateValidationAttribute : ValidationAttribute
{
    public DateValidationAttribute(string leftDateProperty, CompareOperator compareOperator, string rightDateProperty, string errorMessage)
            : base(errorMessage)
    {
        LeftDateProperty = leftDateProperty;
        Operator = compareOperator;
        RightDateProperty = rightDateProperty;
    }
    ...
    ...
}

它在构造函数中需要两个日期属性名称和一个运算符。

在验证方法中,返回语句 LeftDate Operator RightDate 的结果。

public override bool IsValid(object value)
{
    DateTime leftDate;
    DateTime rightDate;

    // Get all properties on the view model
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);

    DateTime rightDate = (DateTime)properties.Find(RightDateProperty, true).GetValue(value);
    DateTime leftDate = (DateTime)properties.Find(LeftDateProperty, true).GetValue(value);

    // Perform rule check
    switch (Operator)
    {
        case CompareOperator.Equal:
            return leftDate.Equals(rightDate);
        case CompareOperator.Greater:                    
            return leftDate > rightDate;
        case CompareOperator.Lesser:                    
            return leftDate < rightDate;
        case CompareOperator.GreaterOrEqual:                    
            return leftDate >= rightDate;
        case CompareOperator.LesserOrEqual:                    
            return leftDate <= rightDate;
        default:
            return false;
    }
}

因为这是一个 AttriuteTargets.Class 属性,我知道框架不可能知道哪个属性导致验证失败。但我知道是 Left Date 属性失败了,因此我想将模型状态中的错误 ID 设置为此属性。这样做的原因是我希望在表单中标记失败的字段。

问题:如何修改添加到ModelState错误集合中的错误项,使其id对应表单中的特定字段?

I have the following ValidationAttribute class

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class DateValidationAttribute : ValidationAttribute
{
    public DateValidationAttribute(string leftDateProperty, CompareOperator compareOperator, string rightDateProperty, string errorMessage)
            : base(errorMessage)
    {
        LeftDateProperty = leftDateProperty;
        Operator = compareOperator;
        RightDateProperty = rightDateProperty;
    }
    ...
    ...
}

It takes two date property names and an operator in the constructor.

In the validation method the result of the statement LeftDate Operator RightDate is returned.

public override bool IsValid(object value)
{
    DateTime leftDate;
    DateTime rightDate;

    // Get all properties on the view model
    PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);

    DateTime rightDate = (DateTime)properties.Find(RightDateProperty, true).GetValue(value);
    DateTime leftDate = (DateTime)properties.Find(LeftDateProperty, true).GetValue(value);

    // Perform rule check
    switch (Operator)
    {
        case CompareOperator.Equal:
            return leftDate.Equals(rightDate);
        case CompareOperator.Greater:                    
            return leftDate > rightDate;
        case CompareOperator.Lesser:                    
            return leftDate < rightDate;
        case CompareOperator.GreaterOrEqual:                    
            return leftDate >= rightDate;
        case CompareOperator.LesserOrEqual:                    
            return leftDate <= rightDate;
        default:
            return false;
    }
}

Because this is an AttriuteTargets.Class attribute I know it is impossible for the framework to know which property that is causing the validation to fail. But I know that it is Left Date Property that is failing and therefore I want to set the Id of the error in the modelstate to this property. The reason for this is that I want the failing field to be marked in the form.

Question: How can I modify the error item added to the error collection in ModelState so that its id corresponds to a specific field in the form?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

删除→记忆 2024-09-15 00:15:56

我找到了一种使用 IDataErrorInfo 执行此操作的更好方法,

这就是我的做法。它不像问题中的例子那么通用。使用此解决方案,您必须对每项检查进行编码。但现在验证将一直很好地工作到 javascript 并突出显示失败的输入元素。

public class TestModel: IDataErrorInfo
{

    public TestModel()
    {
    }

    [Required]
    public string StartDate { get; set; }

    [Required]
    public string EndDate { get; set; }

    #region IDataErrorInfo Members

    public string Error
    {
        get
        {
            return string.Empty;
        }
    }

    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "StartDate":
                    {
                        if (StartDate < DateTime.Today)
                        {
                            return "Start date must not be a date in the past";
                        }
                        break;
                    }
                case "EndDate":
                    {
                        if (EndDate < StartDate)
                        {
                            return "End date must not be a date before start date";
                        }
                        break;
                    }   
                default:
                    return string.Empty;
            }
            return string.Empty;
        }
    }
}

I found a better way of doing this using IDataErrorInfo

Here is how I'm doing it. It's not that generic as the example in the question. With this solution you have to code each check. But now the validation will work nice all the way up to the javascript and highlighting of the failing input element.

public class TestModel: IDataErrorInfo
{

    public TestModel()
    {
    }

    [Required]
    public string StartDate { get; set; }

    [Required]
    public string EndDate { get; set; }

    #region IDataErrorInfo Members

    public string Error
    {
        get
        {
            return string.Empty;
        }
    }

    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "StartDate":
                    {
                        if (StartDate < DateTime.Today)
                        {
                            return "Start date must not be a date in the past";
                        }
                        break;
                    }
                case "EndDate":
                    {
                        if (EndDate < StartDate)
                        {
                            return "End date must not be a date before start date";
                        }
                        break;
                    }   
                default:
                    return string.Empty;
            }
            return string.Empty;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文