切换RequiredAttribute错误消息的语言

时间:2018-03-28 15:21:14

标签: asp.net-mvc localization data-annotations

我使用自定义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"值,但在此之后,即使在页面刷新之后,它也具有已翻译的值。这是为什么?如何解决?

0 个答案:

没有答案