【问题标题】:Translate property name in error messages with FluentValidation使用 FluentValidation 翻译错误消息中的属性名称
【发布时间】:2020-10-08 13:11:30
【问题描述】:

我在我的项目中使用 FluentValidation 来验证几乎所有进入我的 WebApi 的请求。 它工作正常,但我被要求翻译错误消息中的属性名称。我的项目必须至少处理法语和英语,例如,我想要实现的是:

  • 需要“名字”(英文大小写)
  • 'Prénom' est requis(法文案例)

我已经有一个 IPropertyLabelService 用于其他目的,它被注入到 Startup.cs 中,我想使用它。它在 .json 中找到属性名称的翻译,这已经很好了。

我的问题是我不知道如何在全球范围内使用它。我知道 FluentValidation 的文档说要在启动文件中设置 ValidatorOptions.DisplayNameResolver,如下所示:

FluentValidation.ValidatorOptions.DisplayNameResolver = (type, memberInfo, expression) => {
    // Do something
};

我不知道如何在其中使用我的 IPropertyLabelService,因为 Startup.ConfigureServices 方法还没有结束,所以我无法解析我的服务...

任何其他实现此行为的解决方案也非常受欢迎。我考虑过使用 .WithMessage() 或 .WithName() 但我有大量的验证器,要单独添加它会很长。

【问题讨论】:

    标签: asp.net-core dependency-injection asp.net-web-api2 fluentvalidation


    【解决方案1】:

    我在 FluentValidation 问题跟踪器上回答了这个问题,但为了完整起见,这里也将包含答案:

    设置 FluentValidation.ValidatorOptions.Global.DisplayNameResolver 是全局处理此问题的正确方法(或者您可以在单个规则级别使用 WithName)。

    您需要确保在全局范围内设置一次。如果您需要先初始化服务提供者,请确保在配置服务提供者之后调用它(但确保您仍然只设置一次)。

    .NET Core 中的“选项”配置机制允许您将配置推迟到构建点服务之后,因此您可以创建一个实现 IConfigureOptions 的类,该类将在特定的配置阶段被实例化并执行选项类型。 FluentValidation 本身不提供任何选项配置,因此您只需挂钩到内置选项类之一(ASP.NET 的 MvcOptions 可能是最简单的,但如果您不使用 mvc,也可以使用其他选项) .

    例如,您可以在 ConfigureServices 方法中执行以下操作:

     public void ConfigureServices(IServiceCollection services) {
          // ... your normal configuration ...
          services.AddMvc().AddFluentValidation();
    
         // Afterwards define some deferred configuration:
         services.AddSingleton<IConfigureOptions<MvcOptions>, DeferredConfiguration>();
    
    }
    
    // And here's the configuration class. You can inject any services you need in its constructor as with any other DI-enabled service. Make sure your IPropertyLabelService is registered as a singleton. 
    public class DeferredConfiguration : IConfigureOptions<MvcOptions> {
        private IPropertyLabelService _labelService;
    
        public DeferredConfiguration(IPropertyLabelService labelService) {
            _labelService = labelService;
        }
        public void Configure(MvcOptions options) {
            FluentValidation.ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, expression) => {
                return _labelService.GetPropertyOrWhatever(memberInfo.Name);
            };
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多