如何强制 ValidationAttribute 将指定的对象成员标记为无效?

发布于 2024-11-26 00:59:06 字数 820 浏览 0 评论 0原文

我的模型包含一些成员:

public class Address
{
   public Street { get; set;}
   public City { get; set; }
   public PostalCode { get; set; }
}

现在我的 ValidationAttribute 具有 IsValid 方法,如下所示:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var input = value as Address;

    if (string.IsNullOrEmpty(input.City))
        return new ValidationResult("City is required);

    if (!string.IsNullOrEmpty(input.PostalCode))
        if (string.IsNullOrEmpty(input.Street))
            return new ValidationResult("Stret is required");

    return ValidationResult.Success;
}

问题是:

验证我的模型后state 仅将模型错误添加到整个 Adress 成员,但我需要将其添加到城市或街道等指定成员。

对此的任何帮助将不胜感激...谢谢!

I've got my model which contains some members:

public class Address
{
   public Street { get; set;}
   public City { get; set; }
   public PostalCode { get; set; }
}

Now I've got my ValidationAttribute with IsValid method overrided like this:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var input = value as Address;

    if (string.IsNullOrEmpty(input.City))
        return new ValidationResult("City is required);

    if (!string.IsNullOrEmpty(input.PostalCode))
        if (string.IsNullOrEmpty(input.Street))
            return new ValidationResult("Stret is required");

    return ValidationResult.Success;
}

The problem is:

After validation my model state adds model error only to whole Adress member, but I need it to be added to specified members like city or street.

Any help with this will be appreciated... thanks!

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

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

发布评论

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

评论(2

離殇 2024-12-03 00:59:06

您可以添加成员姓名!

return new ValidationResult("City is required", new string[] { "City", "Street" });

编辑:
我已经测试并找到了解决方案:System.ComponentModel.IDataErrorInfo!
这在 javascript 客户端上不起作用,但是在提交结果时我们尝试了:)
所以继续使用 ValidationResult 和 memberNames
并且:

public class myModel : System.ComponentModel.IDataErrorInfo
    {

        private Dictionary<string, List<ValidationResult>> errors;
        private bool IsValidated = false;

        private void Validate()
        {
            errors = new Dictionary<string, List<ValidationResult>>();
            List<ValidationResult> lst = new List<ValidationResult>();
            Validator.TryValidateObject(this, new ValidationContext(this, null, null), lst, true);
            lst.ForEach(vr =>
                {
                    foreach (var memberName in vr.MemberNames)
                        AddError(memberName, vr);
                });
            IsValidated = true;
        }
        private void AddError(string memberName, ValidationResult error)
        {
            if (!errors.ContainsKey(memberName))
                errors[memberName] = new List<ValidationResult>();
            errors[memberName].Add(error);
        }

        public string Error
        {
            get
            {
                if (!IsValidated)
                    Validate();

                return string.Join("\n", errors
                    .Where(kvp => kvp.Value.Any())
                    .Select(kvp => kvp.Key + " : " + string.Join(", ", kvp.Value.Select(err => err.ErrorMessage)))
                    );
            }
        }

        public string this[string columnName]
        {
            get
            {
                if (!IsValidated)
                    Validate();

                if (errors.ContainsKey(columnName))
                {
                    var value = errors[columnName];
                    return string.Join(", ", value.Select(err => err.ErrorMessage));
                }
                else
                    return null;
            }
        }

现在当前属性被标记为错误,memberNames 也是如此!

:D

编辑2

事实上,你可以保留简单的DataAnnotations来通知客户,
在服务器端,您可以添加更复杂的业务验证:

public class myModel : IValidatableObject
{
      public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
      {

            if (string.IsNullOrEmpty(input.City))
                  yield return new ValidationResult("City is required",new string[]{"prop1","prop2"});
            if (!string.IsNullOrEmpty(input.PostalCode))
                  if (string.IsNullOrEmpty(input.Street))
                        yield return new ValidationResult("Stret is required");
      }

请注意,只有当 DataAnnotations 都有效时才调用 Validate 方法!

you can add memberNames !

return new ValidationResult("City is required", new string[] { "City", "Street" });

EDIT :
i've tested and found a solution : System.ComponentModel.IDataErrorInfo !!
this doesn't work on the javascript client, but when submitting the result is what we attempted :)
so keep using the ValidationResult with memberNames
and :

public class myModel : System.ComponentModel.IDataErrorInfo
    {

        private Dictionary<string, List<ValidationResult>> errors;
        private bool IsValidated = false;

        private void Validate()
        {
            errors = new Dictionary<string, List<ValidationResult>>();
            List<ValidationResult> lst = new List<ValidationResult>();
            Validator.TryValidateObject(this, new ValidationContext(this, null, null), lst, true);
            lst.ForEach(vr =>
                {
                    foreach (var memberName in vr.MemberNames)
                        AddError(memberName, vr);
                });
            IsValidated = true;
        }
        private void AddError(string memberName, ValidationResult error)
        {
            if (!errors.ContainsKey(memberName))
                errors[memberName] = new List<ValidationResult>();
            errors[memberName].Add(error);
        }

        public string Error
        {
            get
            {
                if (!IsValidated)
                    Validate();

                return string.Join("\n", errors
                    .Where(kvp => kvp.Value.Any())
                    .Select(kvp => kvp.Key + " : " + string.Join(", ", kvp.Value.Select(err => err.ErrorMessage)))
                    );
            }
        }

        public string this[string columnName]
        {
            get
            {
                if (!IsValidated)
                    Validate();

                if (errors.ContainsKey(columnName))
                {
                    var value = errors[columnName];
                    return string.Join(", ", value.Select(err => err.ErrorMessage));
                }
                else
                    return null;
            }
        }

and now the current property is marked in error, and the memberNames too !

:D

Edit 2

In fact, you can keep simple DataAnnotations to inform client,
and server side, you can add more complex business validation :

public class myModel : IValidatableObject
{
      public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
      {

            if (string.IsNullOrEmpty(input.City))
                  yield return new ValidationResult("City is required",new string[]{"prop1","prop2"});
            if (!string.IsNullOrEmpty(input.PostalCode))
                  if (string.IsNullOrEmpty(input.Street))
                        yield return new ValidationResult("Stret is required");
      }

note that the Validate method is called only when DataAnnotations are all valid !

初见你 2024-12-03 00:59:06

您需要使用 ValidationResultthis 构造函数班级。
例如

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var input = value as Address;

    if (string.IsNullOrEmpty(input.City))
        return new ValidationResult("City is required", new List<string>(){"City"});

    if (!string.IsNullOrEmpty(input.PostalCode))
        if (string.IsNullOrEmpty(input.Street))
            return new ValidationResult("Stret is required", new List<string>(){"Street"});

    return ValidationResult.Success;
}

You need to use this constructor of ValidationResult class.
Eg

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var input = value as Address;

    if (string.IsNullOrEmpty(input.City))
        return new ValidationResult("City is required", new List<string>(){"City"});

    if (!string.IsNullOrEmpty(input.PostalCode))
        if (string.IsNullOrEmpty(input.Street))
            return new ValidationResult("Stret is required", new List<string>(){"Street"});

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