• 本地化ASP.NET core模型绑定错误消息


    默认错误消息:

    MissingBindRequiredValueAccessor    A value for the '{0}' property was not provided.
    MissingKeyOrValueAccessor           A value is required.
    ValueMustNotBeNullAccessor          The value '{0}' is invalid. 
    AttemptedValueIsInvalidAccessor     The value '{0}' is not valid for {1}.
    UnknownValueIsInvalidAccessor       The supplied value is invalid for {0}.
    ValueIsInvalidAccessor              The value '{0}' is invalid.
    ValueMustBeANumberAccessor          The field {0} must be a number.
    MissingRequestBodyRequiredValueAccessor       A non-empty request body is required.
    NonPropertyAttemptedValueIsInvalidAccessor    The value '{0}' is not valid.
    NonPropertyUnknownValueIsInvalidAccessor      The supplied value is invalid.
    NonPropertyValueMustBeANumberAccessor         The field must be a number.

     

    若要本地化ASP.NET Core 模型绑定错误消息,请按照下列步骤操作:

    1. 创建资源文件 - 在解决方案的Resources文件夹下创建资源文件,并将文件命名为ModelBindingMessages.resx名称可以是其他任何名称,但我们将使用它来创建本地化程序。

    2. 添加资源键 - 打开资源文件并添加要用于本地化错误消息的键和值。我使用了键和值

    3. 配置选项 - 在ConfigureServices方法中,添加时Mvc,配置其选项以设置以下内容的消息访问者ModelBindingMessageProvider

    4.  1    services.AddMvc(options =>
       2             {
       3                 IStringLocalizerFactory F = services.BuildServiceProvider().
       4                 GetService<IStringLocalizerFactory>();
       5                 IStringLocalizer L = F.Create("ModelBindingMessages",
       6                     "AspNetCoreLocalizationSample");
       7                 options.ModelBindingMessageProvider.
       8                 SetValueIsInvalidAccessor((x) => L["The value '{0}' is invalid."]);
       9                 options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(
      10                     (x) =>L["The field {0} must be a number."]);
      11                 options.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor(
      12                     (x) => L["A value for the '{0}' property was not provided.", x]);
      13                 options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor(
      14                     (x, y) => L["The value '{0}' is not valid for {1}.", x, y]);
      15                 options.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(
      16                     () => L["A value is required."]);
      17                 options.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor(
      18                     (x) => L["The supplied value is invalid for {0}.", x]);
      19                 options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
      20                     (x) => L["Null value is invalid.", x]);
      21             }).AddDataAnnotationsLocalization()
      22     .AddViewLocalization();
      23     services.Configure<RequestLocalizationOptions>(options =>
      24     {
      25         var supportedCultures = new[]{new CultureInfo("en"), new CultureInfo("zh-cn")};
      26         options.DefaultRequestCulture = new RequestCulture("en", "en");
      27         options.SupportedCultures = supportedCultures;
      28         options.SupportedUICultures = supportedCultures;
      29     });
    5. 还要在Configure方法开头添加此代码:

      1 var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("zh-CN") };
      2 app.UseRequestLocalization(new RequestLocalizationOptions()
      3 {
      4     DefaultRequestCulture = new RequestCulture(new CultureInfo("en")),
      5     SupportedCultures = supportedCultures,
      6     SupportedUICultures = supportedCultures
      7 });
    6. 关于属性DisplayAttribute 

      通过查看源码 在 Microsoft.AspNetCore.Mvc.DataAnnotations.Internal.DataAnnotationsMetadataProvider中有IDisplayMetadataProvider的实现
      主要是判断DisplayName不为空和ResourceType为空的时候使用IStringLocalizerFactory 
      代码片段如下:
        1    var dataTypeAttribute = attributes.OfType<DataTypeAttribute>(). 
        2 if (displayFormatAttribute == null && dataTypeAttribute != null)
        3             {
        4                 displayFormatAttribute = dataTypeAttribute.DisplayFormat;
        5             }
        6             var displayMetadata = context.DisplayMetadata;
        7 
        8             // ConvertEmptyStringToNull
        9             if (displayFormatAttribute != null)
       10             {
       11                 displayMetadata.ConvertEmptyStringToNull = displayFormatAttribute.
       12                     ConvertEmptyStringToNull;
       13             }
       14             // DataTypeName
       15             if (dataTypeAttribute == null)
       16             {
       17                 if (displayFormatAttribute != null && !displayFormatAttribute.HtmlEncode)
       18                 {
       19                     displayMetadata.DataTypeName = DataType.Html.ToString();
       20                 }
       21             }
       22             else
       23             {
       24                 displayMetadata.DataTypeName = dataTypeAttribute.GetDataTypeName();
       25             }
       26 
       27             var containerType = context.Key.ContainerType ?? context.Key.ModelType;
       28             IStringLocalizer localizer = null;
       29             if (_stringLocalizerFactory != null && _localizationOptions.DataAnnotationLocalizerProvider != null)
       30             {
       31                 localizer = _localizationOptions.DataAnnotationLocalizerProvider(containerType, _stringLocalizerFactory);
       32             }
       33 
       34             // Description
       35             if (displayAttribute != null)
       36             {
       37                 if (localizer != null &&
       38                     !string.IsNullOrEmpty(displayAttribute.Description) &&
       39                     displayAttribute.ResourceType == null)
       40                 {
       41                     displayMetadata.Description = () => localizer[displayAttribute.Description];
       42                 }
       43                 else
       44                 {
       45                     displayMetadata.Description = () => displayAttribute.GetDescription();
       46                 }
       47             }
       48 
       49             // DisplayFormatString
       50             if (displayFormatAttribute != null)
       51             {
       52                 displayMetadata.DisplayFormatString = displayFormatAttribute.DataFormatString;
       53             }
       54 
       55             // DisplayName
       56             // DisplayAttribute has precedence over DisplayNameAttribute.
       57             if (displayAttribute?.GetName() == null)
       58             {
       59                 if (displayNameAttribute != null)
       60                 {
       61                     if (localizer != null &&
       62                         !string.IsNullOrEmpty(displayNameAttribute.DisplayName))
       63                     {
       64                         displayMetadata.DisplayName = () => localizer[displayNameAttribute.DisplayName];
       65                     }
       66                     else
       67                     {
       68                         displayMetadata.DisplayName = () => displayNameAttribute.DisplayName;
       69                     }
       70                 }
       71             }
       72             else
       73             {
       74                 if (localizer != null &&
       75                     !string.IsNullOrEmpty(displayAttribute.Name) &&
       76                     displayAttribute.ResourceType == null)
       77                 {
       78                     displayMetadata.DisplayName = () => localizer[displayAttribute.Name];
       79                 }
       80                 else
       81                 {
       82                     displayMetadata.DisplayName = () => displayAttribute.GetName();
       83                 }
       84             }
       85 
       86             // EditFormatString
       87             if (displayFormatAttribute != null && displayFormatAttribute.ApplyFormatInEditMode)
       88             {
       89                 displayMetadata.EditFormatString = displayFormatAttribute.DataFormatString;
       90             }
       91 
       92             // IsEnum et cetera
       93             var underlyingType = Nullable.GetUnderlyingType(context.Key.ModelType) ?? context.Key.ModelType;
       94             var underlyingTypeInfo = underlyingType.GetTypeInfo();
       95 
       96             if (underlyingTypeInfo.IsEnum)
       97             {
       98                 // IsEnum
       99                 displayMetadata.IsEnum = true;
      100 
      101                 // IsFlagsEnum
      102                 displayMetadata.IsFlagsEnum = underlyingTypeInfo.IsDefined(typeof(FlagsAttribute), inherit: false);
      103 
      104                 // EnumDisplayNamesAndValues and EnumNamesAndValues
      105                 //
      106                 // Order EnumDisplayNamesAndValues by DisplayAttribute.Order, then by the order of Enum.GetNames().
      107                 // That method orders by absolute value, then its behavior is undefined (but hopefully stable).
      108                 // Add to EnumNamesAndValues in same order but Dictionary does not guarantee order will be preserved.
      109 
      110                 var groupedDisplayNamesAndValues = new List<KeyValuePair<EnumGroupAndName, string>>();
      111                 var namesAndValues = new Dictionary<string, string>();
      112 
      113                 IStringLocalizer enumLocalizer = null;
      114                 if (_localizationOptions.AllowDataAnnotationsLocalizationForEnumDisplayAttributes)
      115                 {
      116                     if (_stringLocalizerFactory != null && _localizationOptions.DataAnnotationLocalizerProvider != null)
      117                     {
      118                         enumLocalizer = _localizationOptions.DataAnnotationLocalizerProvider(underlyingType, _stringLocalizerFactory);
      119                     }
      120                 }
      121                 else
      122                 {
      123                     enumLocalizer = _stringLocalizerFactory?.Create(underlyingType);
      124                 }
      125 
      126                 var enumFields = Enum.GetNames(underlyingType)
      127                     .Select(name => underlyingType.GetField(name))
      128                     .OrderBy(field => field.GetCustomAttribute<DisplayAttribute>(inherit: false)?.GetOrder() ?? 1000);
      129 
      130                 foreach (var field in enumFields)
      131                 {
      132                     var groupName = GetDisplayGroup(field);
      133                     var value = ((Enum)field.GetValue(obj: null)).ToString("d");
      134 
      135                     groupedDisplayNamesAndValues.Add(new KeyValuePair<EnumGroupAndName, string>(
      136                         new EnumGroupAndName(
      137                             groupName,
      138                             () => GetDisplayName(field, enumLocalizer)),
      139                         value));
      140                     namesAndValues.Add(field.Name, value);
      141                 }
      142 
      143                 displayMetadata.EnumGroupedDisplayNamesAndValues = groupedDisplayNamesAndValues;
      144                 displayMetadata.EnumNamesAndValues = namesAndValues;
      145             }
      146 
      147             // HasNonDefaultEditFormat
      148             if (!string.IsNullOrEmpty(displayFormatAttribute?.DataFormatString) &&
      149                 displayFormatAttribute?.ApplyFormatInEditMode == true)
      150             {
      151                 // Have a non-empty EditFormatString based on [DisplayFormat] from our cache.
      152                 if (dataTypeAttribute == null)
      153                 {
      154                     // Attributes include no [DataType]; [DisplayFormat] was applied directly.
      155                     displayMetadata.HasNonDefaultEditFormat = true;
      156                 }
      157                 else if (dataTypeAttribute.DisplayFormat != displayFormatAttribute)
      158                 {
      159                     // Attributes include separate [DataType] and [DisplayFormat]; [DisplayFormat] provided override.
      160                     displayMetadata.HasNonDefaultEditFormat = true;
      161                 }
      162                 else if (dataTypeAttribute.GetType() != typeof(DataTypeAttribute))
      163                 {
      164                     // Attributes include [DisplayFormat] copied from [DataType] and [DataType] was of a subclass.
      165                     // Assume the [DataType] constructor used the protected DisplayFormat setter to override its
      166                     // default.  That is derived [DataType] provided override.
      167                     displayMetadata.HasNonDefaultEditFormat = true;
      168                 }
      169             }
      170 
      171             // HideSurroundingHtml
      172             if (hiddenInputAttribute != null)
      173             {
      174                 displayMetadata.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;
      175             }
      176 
      177             // HtmlEncode
      178             if (displayFormatAttribute != null)
      179             {
      180                 displayMetadata.HtmlEncode = displayFormatAttribute.HtmlEncode;
      181             }
      182 
      183             // NullDisplayText
      184             if (displayFormatAttribute != null)
      185             {
      186                 displayMetadata.NullDisplayText = displayFormatAttribute.NullDisplayText;
      187             }
      188 
      189             // Order
      190             if (displayAttribute?.GetOrder() != null)
      191             {
      192                 displayMetadata.Order = displayAttribute.GetOrder().Value;
      193             }
      194 
      195             // Placeholder
      196             if (displayAttribute != null)
      197             {
      198                 if (localizer != null &&
      199                     !string.IsNullOrEmpty(displayAttribute.Prompt) &&
      200                     displayAttribute.ResourceType == null)
      201                 {
      202                     displayMetadata.Placeholder = () => localizer[displayAttribute.Prompt];
      203                 }
      204                 else
      205                 {
      206                     displayMetadata.Placeholder = () => displayAttribute.GetPrompt();
      207                 }
      208             }

       
    7.    

    
    
  • 相关阅读:
    百奥谷
    3月13日火箭VS老鹰
    百度 hi 下载地址(内测版,正式版)
    中兴u980
    2008年清明节放假通知
    cyp740703 一个女人的自白
    黄唇鱼
    3月9日火箭vs黄蜂
    3月3日火箭vs掘金
    百度hi邀请码
  • 原文地址:https://www.cnblogs.com/SpeakHero/p/9639676.html
Copyright © 2020-2023  润新知