使用 FluentValidation 翻译错误消息中的 属性 名称
Translate property name in error messages with FluentValidation
我在我的项目中使用 FluentValidation 来验证几乎所有进入我的 WebApi 的请求。
它工作正常,但我被要求翻译错误消息中的 属性 名称。我的项目必须至少处理法语和英语,所以例如,我想要实现的是:
- 'First Name' 为必填项(英文大小写)
- 'Prénom' est requis(法语案例)
我已经有一个用于其他目的的 IPropertyLabelService,它被注入到我想使用的 Startup.cs 中。它在 .json 中找到 属性 名称的翻译,这已经可以正常工作了。
我的问题是我不知道如何在全球范围内使用它。我知道 FluentValidation 的文档说要在启动文件中设置 ValidatorOptions.DisplayNameResolver,像这样:
FluentValidation.ValidatorOptions.DisplayNameResolver = (type, memberInfo, expression) => {
// Do something
};
我不知道如何在其中使用我的 IPropertyLabelService,因为 Startup.ConfigureServices 方法尚未结束,所以我无法解析我的服务...
实现此行为的任何其他解决方案也非常受欢迎。我考虑过使用 .WithMessage() 或 .WithName() 但我有大量的验证器,将其单独添加到所有验证器真的很长。
我在 FluentValidation 问题跟踪器上回答了这个问题,但为了完整起见,这里也包括答案:
Ssetting FluentValidation.ValidatorOptions.Global.DisplayNameResolver
是全局处理此问题的正确方法(或者您可以在单个规则级别使用 WithName)。
您需要确保这是一次全局设置。如果您需要先初始化服务提供者,请确保在配置服务提供者之后调用它(但确保您仍然只设置一次)。
.NET Core 中的“选项”配置机制允许您将配置推迟到构建点服务之后,因此您可以创建一个 class 实现 IConfigureOptions,它将在特定选项类型的配置阶段。 FluentValidation 本身不提供任何选项配置,因此您可以只挂钩 built-in 选项之一 classes(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);
};
}
}
我在我的项目中使用 FluentValidation 来验证几乎所有进入我的 WebApi 的请求。 它工作正常,但我被要求翻译错误消息中的 属性 名称。我的项目必须至少处理法语和英语,所以例如,我想要实现的是:
- 'First Name' 为必填项(英文大小写)
- 'Prénom' est requis(法语案例)
我已经有一个用于其他目的的 IPropertyLabelService,它被注入到我想使用的 Startup.cs 中。它在 .json 中找到 属性 名称的翻译,这已经可以正常工作了。
我的问题是我不知道如何在全球范围内使用它。我知道 FluentValidation 的文档说要在启动文件中设置 ValidatorOptions.DisplayNameResolver,像这样:
FluentValidation.ValidatorOptions.DisplayNameResolver = (type, memberInfo, expression) => {
// Do something
};
我不知道如何在其中使用我的 IPropertyLabelService,因为 Startup.ConfigureServices 方法尚未结束,所以我无法解析我的服务...
实现此行为的任何其他解决方案也非常受欢迎。我考虑过使用 .WithMessage() 或 .WithName() 但我有大量的验证器,将其单独添加到所有验证器真的很长。
我在 FluentValidation 问题跟踪器上回答了这个问题,但为了完整起见,这里也包括答案:
Ssetting FluentValidation.ValidatorOptions.Global.DisplayNameResolver
是全局处理此问题的正确方法(或者您可以在单个规则级别使用 WithName)。
您需要确保这是一次全局设置。如果您需要先初始化服务提供者,请确保在配置服务提供者之后调用它(但确保您仍然只设置一次)。
.NET Core 中的“选项”配置机制允许您将配置推迟到构建点服务之后,因此您可以创建一个 class 实现 IConfigureOptions,它将在特定选项类型的配置阶段。 FluentValidation 本身不提供任何选项配置,因此您可以只挂钩 built-in 选项之一 classes(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);
};
}
}