使用数据注释进行模型验证的错误消息

发布于 2024-08-31 19:21:26 字数 614 浏览 3 评论 0原文

给定以下类:

using System.ComponentModel.DataAnnotations;

public class Book{
   public Contact PrimaryContact{get; set;}
   public Contact SecondaryContact{get; set;}

   [Required(ErrorMessage="Book name is required")]
   public string Name{get; set;}
}
public class Contact{
    [Required(ErrorMessage="Name is required")]
    public string Name{get; set;}
}

是否有一种干净的方法可以使用 DataAnnotations 为 Book 中的每个 Contact 实例提供不同的错误消息?例如,如果 PrimaryContact 实例中缺少姓名,则错误将显示为“需要主要联系人姓名”。

我当前的解决方案是创建一个验证服务,检查模型状态中的字段错误,然后删除所述错误并使用我想要的特定语言将它们添加回来。

Given the following classes:

using System.ComponentModel.DataAnnotations;

public class Book{
   public Contact PrimaryContact{get; set;}
   public Contact SecondaryContact{get; set;}

   [Required(ErrorMessage="Book name is required")]
   public string Name{get; set;}
}
public class Contact{
    [Required(ErrorMessage="Name is required")]
    public string Name{get; set;}
}

Is there a clean way I can give a distinct error message for each instance of Contact in Book using DataAnnotations? For example, if the name was missing from the PrimaryContact instance the error would read "primary contact name is required".

My current solution is to create a validation service that checks the model state for field errors, then remove said errors and add them back using the specific language I'd like.

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

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

发布评论

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

评论(4

囚你心 2024-09-07 19:21:26

这是我所知道的唯一方法,但它远非干净。它涉及使用子类化和元数据类来“覆盖”错误消息。

public class Book
{
    public PrimaryContact PrimaryContact { get; set; }
    public SecondaryContact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }
}

public class Contact
{
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

[MetadataType(typeof(PrimaryContactMD))]
public class PrimaryContact : Contact
{
    class PrimaryContactMD
    {
        [Required(ErrorMessage = "Primary Contact Name is required")]
        public string Name { get; set; }
    }
}

[MetadataType(typeof(SecondaryContactMD))]
public class SecondaryContact : Contact
{
    class SecondaryContactMD
    {
        [Required(ErrorMessage = "Secondary Contact Name is required")]
        public string Name { get; set; }
    }
}

This is the only way I know of that, but it's far from clean. It involves using subclassing and MetaData classes to "override" the error message.

public class Book
{
    public PrimaryContact PrimaryContact { get; set; }
    public SecondaryContact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }
}

public class Contact
{
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

[MetadataType(typeof(PrimaryContactMD))]
public class PrimaryContact : Contact
{
    class PrimaryContactMD
    {
        [Required(ErrorMessage = "Primary Contact Name is required")]
        public string Name { get; set; }
    }
}

[MetadataType(typeof(SecondaryContactMD))]
public class SecondaryContact : Contact
{
    class SecondaryContactMD
    {
        [Required(ErrorMessage = "Secondary Contact Name is required")]
        public string Name { get; set; }
    }
}
天冷不及心凉 2024-09-07 19:21:26

您可能需要考虑对此类属性使用 CustomValidation 属性,而不是依赖 Required 属性。

CustomValidation 将允许您更精细地根据您正在验证的属性定制验证消息。为了简洁起见,我使用了 context.DisplayName 来动态显示正在验证的属性的名称,但这可以根据您的需要进一步自定义。

如果需要进一步自定义,您可以为每个单独的属性编写不同的 CustomValidation 处理程序,而不是像我在代码示例中那样重复使用相同的处理程序。

using System.ComponentModel.DataAnnotations;

public class Book {
    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact PrimaryContact { get; set; }

    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }

    public static ValidationResult ValidateContact(Contact contact, ValidationContext context) {
        ValidationResult result = null;

        if (contact == null) {
            result = new ValidationResult($"{context.DisplayName} is required.");
        } else if (string.IsNullOrWhiteSpace(contact.Name)) {
            result = new ValidationResult($"{context.DisplayName} name is required.");
        }

        return result;
    }
}

public class Contact {
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}

You may want to look at using the CustomValidation attribute for such properties instead of relying on the Required attribute.

CustomValidation will allow you to more granularly tailor your validation messages to the property you are validating. I've used context.DisplayName to dynamically display the name of the property being validated just for brevity, but this can be customized further based on your needs.

If even further customization is needed, you can write different CustomValidation handlers for each individual property instead of just reusing the same one as I've done in my code example.

using System.ComponentModel.DataAnnotations;

public class Book {
    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact PrimaryContact { get; set; }

    [CustomValidation(typeof(Book), "ValidateContact")]
    public Contact SecondaryContact { get; set; }

    [Required(ErrorMessage = "Book name is required")]
    public string Name { get; set; }

    public static ValidationResult ValidateContact(Contact contact, ValidationContext context) {
        ValidationResult result = null;

        if (contact == null) {
            result = new ValidationResult(
quot;{context.DisplayName} is required.");
        } else if (string.IsNullOrWhiteSpace(contact.Name)) {
            result = new ValidationResult(
quot;{context.DisplayName} name is required.");
        }

        return result;
    }
}

public class Contact {
    [Required(ErrorMessage = "Name is required")]
    public string Name { get; set; }
}
八巷 2024-09-07 19:21:26

下面的 C# 代码用于格式化数据注释错误并以附加格式格式化单个字符串

  public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                if (actionContext.ModelState.IsValid) return;
                string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));
            }
        }
    }

The Below code in c# to format data annotations error and format in append format in single string

  public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                if (actionContext.ModelState.IsValid) return;
                string errors = actionContext.ModelState.SelectMany(state => state.Value.Errors).Aggregate("", (current, error) => current + (error.ErrorMessage + ". "));
            }
        }
    }
夜访吸血鬼 2024-09-07 19:21:26

我也在寻找这个问题的答案,到目前为止我发现如果您在错误消息中执行类似以下操作:“需要{0}联系人姓名”,它会自动替换变量的名称。我认为有一种方法可以显式地使用此功能。

I'm looking for answer to this too, what I have found so far if you do something like: "{0} Contact Name is required" in the Error message it will automatically substitute the name of the variable. I figure there is a way to explicitly use this feature.

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