Asp.net core ASP.NET核心自定义验证错误消息未本地化
我想在自定义属性中实现本地化,以检查该属性是否为有效的IP地址或主机名。到目前为止,验证工作正常,但我的问题是,虽然我的本地语言已切换为德语,但我只收到默认的英语错误消息。我正在处理资源文件。我不想为此实现客户端验证。我知道有一种方法可以实现适配器,但如果我错了,请纠正我,这只是用于客户端验证 我的自定义验证类:Asp.net core ASP.NET核心自定义验证错误消息未本地化,asp.net-core,custom-attributes,asp.net-core-localization,Asp.net Core,Custom Attributes,Asp.net Core Localization,我想在自定义属性中实现本地化,以检查该属性是否为有效的IP地址或主机名。到目前为止,验证工作正常,但我的问题是,虽然我的本地语言已切换为德语,但我只收到默认的英语错误消息。我正在处理资源文件。我不想为此实现客户端验证。我知道有一种方法可以实现适配器,但如果我错了,请纠正我,这只是用于客户端验证 我的自定义验证类: public class IPAddressOrHostnameAttribute : ValidationAttribute { public IPAddressOrHos
public class IPAddressOrHostnameAttribute : ValidationAttribute
{
public IPAddressOrHostnameAttribute(string propertyName, object desiredvalue, string errorMessage)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
ErrorMessage = errorMessage;
}
private string PropertyName { get; }
private object DesiredValue { get; }
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var instance = context.ObjectInstance;
var type = instance.GetType();
var propertyValue = type.GetProperty(PropertyName).GetValue(instance, null);
if (propertyValue.ToString() == DesiredValue.ToString() && value != null)
{
if (Regex.IsMatch(value.ToString(), AckConstants.VALIDIPADDRESSREGEX)
|| Regex.IsMatch(value.ToString(), AckConstants.VALIDHOSTNAMEREGEX))
{
return ValidationResult.Success;
}
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
}
[Required(ErrorMessage = "The field {0} is required")]
[RegularExpression(@"^\S*$", ErrorMessage = "No white spaces allowed.")]
[IPAddressOrHostname(nameof(IsFileAdapter), true, "Please enter a valid IP address or hostname")]
[IPAddress(nameof(IsFileAdapter), false, "Please enter a valid IP address")]
[Display(Name = "Destination")]
public string Destination { get; set; }
我的模型类:public class IPAddressOrHostnameAttribute : ValidationAttribute
{
public IPAddressOrHostnameAttribute(string propertyName, object desiredvalue, string errorMessage)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
ErrorMessage = errorMessage;
}
private string PropertyName { get; }
private object DesiredValue { get; }
protected override ValidationResult IsValid(object value, ValidationContext context)
{
var instance = context.ObjectInstance;
var type = instance.GetType();
var propertyValue = type.GetProperty(PropertyName).GetValue(instance, null);
if (propertyValue.ToString() == DesiredValue.ToString() && value != null)
{
if (Regex.IsMatch(value.ToString(), AckConstants.VALIDIPADDRESSREGEX)
|| Regex.IsMatch(value.ToString(), AckConstants.VALIDHOSTNAMEREGEX))
{
return ValidationResult.Success;
}
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
}
[Required(ErrorMessage = "The field {0} is required")]
[RegularExpression(@"^\S*$", ErrorMessage = "No white spaces allowed.")]
[IPAddressOrHostname(nameof(IsFileAdapter), true, "Please enter a valid IP address or hostname")]
[IPAddress(nameof(IsFileAdapter), false, "Please enter a valid IP address")]
[Display(Name = "Destination")]
public string Destination { get; set; }
我的startup类配置DataAnnotationLocalizerProvider
:services
.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix,
opts => { opts.ResourcesPath = "Resources"; })
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource)); // SharedResource is the class where the DataAnnotations (translations) will be stored.
})
本地化适用于默认属性,例如Required
等,但不适用于我的自定义验证属性。我不知道我的代码出了什么问题。我已经阅读了stackoverflow文章,但我不明白为什么我的服务器端本地化验证不起作用。希望有人能帮助我,或者给我一个如何让它工作的例子,因为这个问题快把我逼疯了
我不想为此实现客户端验证。我知道有一种方法可以实现适配器,但如果我错了,请纠正我,这只是用于客户端验证
事实上,这不是事实。适配器并不意味着您必须使用客户端验证。请看
至于您的问题本身,您可以创建一个适配器
,还可以创建一个适配器提供程序
,以提供适配器:
公共类IPAddressOrHostnameAttributeAdapter:AttributeAdapterBase
{
公共IPAddressOrHostnameAttributeAdapter(IPAddressOrHostnameAttribute属性,IStringLocalizer stringLocalizer)
:base(属性,stringLocalizer)
{ }
公共重写void AddValidation(ClientModelValidationContext){}
公共重写字符串GetErrorMessage(ModelValidationContextBase validationContext)
{
返回GetErrorMessage(validationContext.ModelMetadata,validationContext.ModelMetadata.GetDisplayName());
}
}
公共类IPAddressOrHostnameAttributeAdapterProvider:IValidationAttributeAdapterProvider
{
private readonly IValizationAttributeAdapterProvider fallback=新的ValidationAttributeAdapterProvider();
public IAttributeAdapter GetAttributeAdapter(验证属性,IStringLocalizer stringLocalizer)
{
var attr=作为IPAddressOrHostnameAttribute的属性;
返回attr==null?
this.fallback.GetAttributeAdapter(属性,stringLocalizer):
新的IPAddressOrHostnameAttributeAdapter(attr,stringLocalizer);
}
}
此外,请确保此服务已在DI容器中注册:
services.AddSingleton();
最后,如果您使用querystring作为区域性提供程序,请不要忘记在表单操作中附加culture=de
:
@{ var __culture = Context.Features.Get<IRequestCultureFeature>().RequestCulture.Culture.ToString(); }
<form asp-action="Create" asp-route-culture="@__culture">
....
</form>
@{var\uuu culture=Context.Features.Get().RequestCulture.culture.ToString();}
....
演示的屏幕截图 我不想为此实现客户端验证。我知道有一种方法可以实现适配器,但如果我错了,请纠正我,这只是用于客户端验证 事实上,这不是事实。适配器并不意味着您必须使用客户端验证。请看 至于您的问题本身,您可以创建一个
适配器
,还可以创建一个适配器提供程序
,以提供适配器:
公共类IPAddressOrHostnameAttributeAdapter:AttributeAdapterBase
{
公共IPAddressOrHostnameAttributeAdapter(IPAddressOrHostnameAttribute属性,IStringLocalizer stringLocalizer)
:base(属性,stringLocalizer)
{ }
公共重写void AddValidation(ClientModelValidationContext){}
公共重写字符串GetErrorMessage(ModelValidationContextBase validationContext)
{
返回GetErrorMessage(validationContext.ModelMetadata,validationContext.ModelMetadata.GetDisplayName());
}
}
公共类IPAddressOrHostnameAttributeAdapterProvider:IValidationAttributeAdapterProvider
{
private readonly IValizationAttributeAdapterProvider fallback=新的ValidationAttributeAdapterProvider();
public IAttributeAdapter GetAttributeAdapter(验证属性,IStringLocalizer stringLocalizer)
{
var attr=作为IPAddressOrHostnameAttribute的属性;
返回attr==null?
this.fallback.GetAttributeAdapter(属性,stringLocalizer):
新的IPAddressOrHostnameAttributeAdapter(attr,stringLocalizer);
}
}
此外,请确保此服务已在DI容器中注册:
services.AddSingleton();
最后,如果您使用querystring作为区域性提供程序,请不要忘记在表单操作中附加culture=de
:
@{ var __culture = Context.Features.Get<IRequestCultureFeature>().RequestCulture.Culture.ToString(); }
<form asp-action="Create" asp-route-culture="@__culture">
....
</form>
@{var\uuu culture=Context.Features.Get().RequestCulture.culture.ToString();}
....
演示的屏幕截图
创建适配器可能是一个解决方案,但太贵了!您必须创建适配器,然后创建适配器提供程序,然后需要在启动时注册它!工作太多了 较短的解决方案是通过
ValidationContext.GetService
在自定义验证属性中获取本地化服务:
如果您正在使用内置本地化服务,它将是IStringLocalizer
,如果您正在使用自定义本地化服务,例如(MyLocalizer),您可以通过将其解析到GetService(typeof(MyLocalizer))
方法来访问它。见以下示例:
protected override ValidationResult有效(对象值,ValidationContext ValidationContext)
{
var_localizationService=(IStringLocalizer)validationContext.GetService(typeof(IStringLocalizer));
var localizedError=_本地化服务[ErrorMessage];
//
//做你的特写