自定义 ValidationAttribute 的 ValidationErrors 未正确显示

发布于 2024-12-16 20:00:00 字数 2630 浏览 2 评论 0原文

我创建了一个在服务器和客户端之间共享的 ValidationAttribute。为了让验证属性在数据帮助器类中引用时正确生成给客户端,我必须非常具体地构建它。

我遇到的问题是,由于某种原因,当我从自定义验证属性类返回 ValidationResult 时,它的处理方式与客户端 UI 上的其他验证属性不同。它不显示错误,而是不执行任何操作。虽然它会正确验证对象,但它只是不显示失败的验证结果。

下面是我的自定义验证类之一的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;

namespace Project.Web.DataLayer.ValidationAttributes
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class DisallowedChars : ValidationAttribute
    {
        public string DisallowedCharacters
        {
            get
            {
                return new string(this.disallowedCharacters);
            }

            set
            {
                this.disallowedCharacters = (!this.CaseSensitive ?     value.ToLower().ToCharArray() : value.ToCharArray());
            }
        }

        private char[] disallowedCharacters = null;

        private bool caseSensitive;

        public bool CaseSensitive
        {
            get
            {
                return this.caseSensitive;
            }

            set
            {
                this.caseSensitive = value;
            }
        }

        protected override ValidationResult IsValid(object value, ValidationContext    validationContext)
        {
            if (value != null && this.disallowedCharacters.Count() > 0)
            {
                string Value = value.ToString();

                foreach(char val in this.disallowedCharacters)
                {
                    if ((!this.CaseSensitive && Value.ToLower().Contains(val)) ||     Value.Contains(val))
                    {
                        return new ValidationResult(string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString()));
                    }
                }
            }

            return ValidationResult.Success;
        }
    }
}

这就是我在服务器和客户端上的“属性”上方使用它的方式。

[DisallowedChars(DisallowedCharacters = "=")]

我尝试了几种不同的设置绑定的方法。

{Binding Value, NotifyOnValidationError=True}

这些似乎都

{Binding Value, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}

没有使它们所绑定的表单也验证条目。我尝试在绑定到 TextBoxes、XamGrids 的值上使用此属性,但这些值都没有像应有的那样正确验证。

这个问题似乎只出现在我尝试在服务器端使用 ValidationResult 时。如果我对视图模型中的值使用验证结果,那么它将正确验证。不过,我需要找到一种方法来从生成的代码中正确验证这一点。

任何想法将不胜感激。

I have a ValidationAttribute that I have created which is shared between the Server, and Client. In order to get the validation attribute to properly generate to the client when referenced within a data helper class I had to be very specific in how I built it.

The problem I'm having is that for some reason when I return a ValidationResult from my custom validation attribute class it is not handled the same as other validation attributes on the client UI. Instead of displaying the error it does nothing. It will properly validate the object though, it just doesn't display the failed validation result.

Below is the code for one of my custom validation classes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;

namespace Project.Web.DataLayer.ValidationAttributes
{
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class DisallowedChars : ValidationAttribute
    {
        public string DisallowedCharacters
        {
            get
            {
                return new string(this.disallowedCharacters);
            }

            set
            {
                this.disallowedCharacters = (!this.CaseSensitive ?     value.ToLower().ToCharArray() : value.ToCharArray());
            }
        }

        private char[] disallowedCharacters = null;

        private bool caseSensitive;

        public bool CaseSensitive
        {
            get
            {
                return this.caseSensitive;
            }

            set
            {
                this.caseSensitive = value;
            }
        }

        protected override ValidationResult IsValid(object value, ValidationContext    validationContext)
        {
            if (value != null && this.disallowedCharacters.Count() > 0)
            {
                string Value = value.ToString();

                foreach(char val in this.disallowedCharacters)
                {
                    if ((!this.CaseSensitive && Value.ToLower().Contains(val)) ||     Value.Contains(val))
                    {
                        return new ValidationResult(string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString()));
                    }
                }
            }

            return ValidationResult.Success;
        }
    }
}

This is how I use it above my Properties on both the server, and client.

[DisallowedChars(DisallowedCharacters = "=")]

And I've tried several different ways of setting up the binding.

{Binding Value, NotifyOnValidationError=True}

As well as

{Binding Value, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}

None of these seem to make the forms that they are bound too validate the entries. I've tried using this attribute on values that are bound to TextBoxes, XamGrids, and neither of those properly validate like they should.

This problem only seems to be when I am attempting to use the ValidationResult on the server side. If I use the validation result on a value in my view model then it will properly validate. I need to find a way to make this properly validate from the generated code though.

Any thoughts would be very much appreciated.

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

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

发布评论

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

评论(1

久而酒知 2024-12-23 20:00:00

您需要指定与 ValidationResult 关联的 MemberName。 ValidationResult 的构造函数有一个附加参数来指定与结果关联的属性。如果不指定任何属性,结果将作为实体级别的验证错误进行处理。

因此,在您的情况下,当您将属性名称传递给 ValidationResult 的构造函数时,应该修复它。

protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
 if (value != null && this.disallowedCharacters.Count() > 0) {
   string Value = value.ToString();

   foreach(char val in this.disallowedCharacters) {
     if ((!this.CaseSensitive && Value.ToLower().Contains(val)) || Value.Contains(val)) {
       //return new ValidationResult(string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString()));
       string errorMessage = string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString());
       return new ValidationResult(errorMessage, new string[] { validationContext.MemberName});
     }
   }
 }

 return ValidationResult.Success;
}

对于绑定,您不需要指定任何其他内容。因此,简单的 Binding

{Binding Value}

应该显示错误,因为 ValidatesOnNotifyDataErrors 隐式设置为 true。 NotifyOnValidationError 将 ValidationErrors 填充到其他元素,例如 ValidationSummary。

Jeff Handly 有一篇关于 WCF Ria 服务中的验证的非常好的博客文章 Silverlight,我可以推荐阅读。

You need to specify the MemberNames that are associated with the ValidationResult. The constructor of ValidationResult has an additional parameter to specify the properties that are associated with the result. If you do not specify any properties, the result is handled as a validation error on entity level.

So in your case, it should be fixed, when you pass in the name of the property to the constructor of the ValidationResult.

protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
 if (value != null && this.disallowedCharacters.Count() > 0) {
   string Value = value.ToString();

   foreach(char val in this.disallowedCharacters) {
     if ((!this.CaseSensitive && Value.ToLower().Contains(val)) || Value.Contains(val)) {
       //return new ValidationResult(string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString()));
       string errorMessage = string.Format(this.ErrorMessage != null ? this.ErrorMessage : "'{0}' is not allowed an allowed character.", val.ToString());
       return new ValidationResult(errorMessage, new string[] { validationContext.MemberName});
     }
   }
 }

 return ValidationResult.Success;
}

For the bindings you don´t need to specify anything else. So the simple Binding

{Binding Value}

should display errors, cause ValidatesOnNotifyDataErrors is set to true implicitly. NotifyOnValidationError populates ValidationErrors to other elements like ValidationSummary.

Jeff Handly has a really goog blog post about Validation in WCF Ria Services and Silverlight, i can recommened to read.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文