我使用自定义DataAnnotationsModelMetadataProvider
将错误消息转换为不同的语言(翻译存储在数据库中)。类看起来像这样:
public class LocalizationModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
var localizationService = new Lazy<ILocalizationService>(() =>
{
return DependencyResolver.Current.GetService<ILocalizationService>();
});
var attrs = attributes.ToList();
var data = base.CreateMetadata(
attrs,
containerType,
modelAccessor,
modelType,
propertyName);
var display = attrs.OfType<DisplayAttribute>().FirstOrDefault();
if (display != null && display.ResourceType == typeof(Resources))
{
data.DisplayName = localizationService.Value.Localize(display.Name);
}
var required = attrs.OfType<RequiredAttribute>().FirstOrDefault();
if (required != null && required.ErrorMessageResourceType == typeof(Resources))
{
var errorResourceName = required.ErrorMessageResourceName;
required.ErrorMessageResourceName = null;
required.ErrorMessageResourceType = null;
required.ErrorMessage = string.IsNullOrEmpty(errorResourceName) ?
string.Format(localizationService.Value.Localize(Local.Common.Required_validation), data.DisplayName) :
string.Format(localizationService.Value.Localize(errorResourceName), data.DisplayName);
}
return data;
}
}
我在Global.asax.cs中注册
protected void Application_Start()
{
//...
ModelMetadataProviders.Current = new LocalizationModelMetadataProvider();
//...
}
这些错误消息的典型用例是声明必填字段
[Required(ErrorMessageResourceName = "Required_validation", ErrorMessageResourceType = typeof(Resources))]
[Display(ResourceType = typeof(Resources), Name = "Customer_name")]
public string CustomerName { get; set; }
并将其显示在视图
上 @Html.TextBoxFor(m => m.CustomerName, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.CustomerName)
效果很好 - 但只有在用户切换语言之前。之后,RequiredAttribute的消息仍然以旧语言翻译。 (同时DisplayAttribute被正确翻译。)初始语言可以是任何语言,并且RequiredAttribute消息将被正确地翻译成这种语言,但它看起来像在第一次翻译后,消息以某种方式被缓存并且不再被翻译。
调试时,在第一次点击
之后var required = attrs.OfType<RequiredAttribute>().FirstOrDefault();
required.ErrorMessageResourceName
对于属性CustomerName具有正确的"Required_validation"
值,但在此之后,即使在页面刷新之后,它也具有已翻译的值。这是为什么?如何解决?