默认错误消息:

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.     services.AddMvc(options =>
    {
    IStringLocalizerFactory F = services.BuildServiceProvider().
    GetService<IStringLocalizerFactory>();
    IStringLocalizer L = F.Create("ModelBindingMessages",
    "AspNetCoreLocalizationSample");
    options.ModelBindingMessageProvider.
    SetValueIsInvalidAccessor((x) => L["The value '{0}' is invalid."]);
    options.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(
    (x) =>L["The field {0} must be a number."]);
    options.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor(
    (x) => L["A value for the '{0}' property was not provided.", x]);
    options.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor(
    (x, y) => L["The value '{0}' is not valid for {1}.", x, y]);
    options.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(
    () => L["A value is required."]);
    options.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor(
    (x) => L["The supplied value is invalid for {0}.", x]);
    options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
    (x) => L["Null value is invalid.", x]);
    }).AddDataAnnotationsLocalization()
    .AddViewLocalization();
    services.Configure<RequestLocalizationOptions>(options =>
    {
    var supportedCultures = new[]{new CultureInfo("en"), new CultureInfo("zh-cn")};
    options.DefaultRequestCulture = new RequestCulture("en", "en");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    });
  5. 还要在Configure方法开头添加此代码:

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

    通过查看源码 在 Microsoft.AspNetCore.Mvc.DataAnnotations.Internal.DataAnnotationsMetadataProvider中有IDisplayMetadataProvider的实现
    主要是判断DisplayName不为空和ResourceType为空的时候使用IStringLocalizerFactory 
    代码片段如下:

        var dataTypeAttribute = attributes.OfType<DataTypeAttribute>().
    if (displayFormatAttribute == null && dataTypeAttribute != null)
    {
    displayFormatAttribute = dataTypeAttribute.DisplayFormat;
    }
    var displayMetadata = context.DisplayMetadata; // ConvertEmptyStringToNull
    if (displayFormatAttribute != null)
    {
    displayMetadata.ConvertEmptyStringToNull = displayFormatAttribute.
    ConvertEmptyStringToNull;
    }
    // DataTypeName
    if (dataTypeAttribute == null)
    {
    if (displayFormatAttribute != null && !displayFormatAttribute.HtmlEncode)
    {
    displayMetadata.DataTypeName = DataType.Html.ToString();
    }
    }
    else
    {
    displayMetadata.DataTypeName = dataTypeAttribute.GetDataTypeName();
    } var containerType = context.Key.ContainerType ?? context.Key.ModelType;
    IStringLocalizer localizer = null;
    if (_stringLocalizerFactory != null && _localizationOptions.DataAnnotationLocalizerProvider != null)
    {
    localizer = _localizationOptions.DataAnnotationLocalizerProvider(containerType, _stringLocalizerFactory);
    } // Description
    if (displayAttribute != null)
    {
    if (localizer != null &&
    !string.IsNullOrEmpty(displayAttribute.Description) &&
    displayAttribute.ResourceType == null)
    {
    displayMetadata.Description = () => localizer[displayAttribute.Description];
    }
    else
    {
    displayMetadata.Description = () => displayAttribute.GetDescription();
    }
    } // DisplayFormatString
    if (displayFormatAttribute != null)
    {
    displayMetadata.DisplayFormatString = displayFormatAttribute.DataFormatString;
    } // DisplayName
    // DisplayAttribute has precedence over DisplayNameAttribute.
    if (displayAttribute?.GetName() == null)
    {
    if (displayNameAttribute != null)
    {
    if (localizer != null &&
    !string.IsNullOrEmpty(displayNameAttribute.DisplayName))
    {
    displayMetadata.DisplayName = () => localizer[displayNameAttribute.DisplayName];
    }
    else
    {
    displayMetadata.DisplayName = () => displayNameAttribute.DisplayName;
    }
    }
    }
    else
    {
    if (localizer != null &&
    !string.IsNullOrEmpty(displayAttribute.Name) &&
    displayAttribute.ResourceType == null)
    {
    displayMetadata.DisplayName = () => localizer[displayAttribute.Name];
    }
    else
    {
    displayMetadata.DisplayName = () => displayAttribute.GetName();
    }
    } // EditFormatString
    if (displayFormatAttribute != null && displayFormatAttribute.ApplyFormatInEditMode)
    {
    displayMetadata.EditFormatString = displayFormatAttribute.DataFormatString;
    } // IsEnum et cetera
    var underlyingType = Nullable.GetUnderlyingType(context.Key.ModelType) ?? context.Key.ModelType;
    var underlyingTypeInfo = underlyingType.GetTypeInfo(); if (underlyingTypeInfo.IsEnum)
    {
    // IsEnum
    displayMetadata.IsEnum = true; // IsFlagsEnum
    displayMetadata.IsFlagsEnum = underlyingTypeInfo.IsDefined(typeof(FlagsAttribute), inherit: false); // EnumDisplayNamesAndValues and EnumNamesAndValues
    //
    // Order EnumDisplayNamesAndValues by DisplayAttribute.Order, then by the order of Enum.GetNames().
    // That method orders by absolute value, then its behavior is undefined (but hopefully stable).
    // Add to EnumNamesAndValues in same order but Dictionary does not guarantee order will be preserved. var groupedDisplayNamesAndValues = new List<KeyValuePair<EnumGroupAndName, string>>();
    var namesAndValues = new Dictionary<string, string>(); IStringLocalizer enumLocalizer = null;
    if (_localizationOptions.AllowDataAnnotationsLocalizationForEnumDisplayAttributes)
    {
    if (_stringLocalizerFactory != null && _localizationOptions.DataAnnotationLocalizerProvider != null)
    {
    enumLocalizer = _localizationOptions.DataAnnotationLocalizerProvider(underlyingType, _stringLocalizerFactory);
    }
    }
    else
    {
    enumLocalizer = _stringLocalizerFactory?.Create(underlyingType);
    } var enumFields = Enum.GetNames(underlyingType)
    .Select(name => underlyingType.GetField(name))
    .OrderBy(field => field.GetCustomAttribute<DisplayAttribute>(inherit: false)?.GetOrder() ?? ); foreach (var field in enumFields)
    {
    var groupName = GetDisplayGroup(field);
    var value = ((Enum)field.GetValue(obj: null)).ToString("d"); groupedDisplayNamesAndValues.Add(new KeyValuePair<EnumGroupAndName, string>(
    new EnumGroupAndName(
    groupName,
    () => GetDisplayName(field, enumLocalizer)),
    value));
    namesAndValues.Add(field.Name, value);
    } displayMetadata.EnumGroupedDisplayNamesAndValues = groupedDisplayNamesAndValues;
    displayMetadata.EnumNamesAndValues = namesAndValues;
    } // HasNonDefaultEditFormat
    if (!string.IsNullOrEmpty(displayFormatAttribute?.DataFormatString) &&
    displayFormatAttribute?.ApplyFormatInEditMode == true)
    {
    // Have a non-empty EditFormatString based on [DisplayFormat] from our cache.
    if (dataTypeAttribute == null)
    {
    // Attributes include no [DataType]; [DisplayFormat] was applied directly.
    displayMetadata.HasNonDefaultEditFormat = true;
    }
    else if (dataTypeAttribute.DisplayFormat != displayFormatAttribute)
    {
    // Attributes include separate [DataType] and [DisplayFormat]; [DisplayFormat] provided override.
    displayMetadata.HasNonDefaultEditFormat = true;
    }
    else if (dataTypeAttribute.GetType() != typeof(DataTypeAttribute))
    {
    // Attributes include [DisplayFormat] copied from [DataType] and [DataType] was of a subclass.
    // Assume the [DataType] constructor used the protected DisplayFormat setter to override its
    // default. That is derived [DataType] provided override.
    displayMetadata.HasNonDefaultEditFormat = true;
    }
    } // HideSurroundingHtml
    if (hiddenInputAttribute != null)
    {
    displayMetadata.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue;
    } // HtmlEncode
    if (displayFormatAttribute != null)
    {
    displayMetadata.HtmlEncode = displayFormatAttribute.HtmlEncode;
    } // NullDisplayText
    if (displayFormatAttribute != null)
    {
    displayMetadata.NullDisplayText = displayFormatAttribute.NullDisplayText;
    } // Order
    if (displayAttribute?.GetOrder() != null)
    {
    displayMetadata.Order = displayAttribute.GetOrder().Value;
    } // Placeholder
    if (displayAttribute != null)
    {
    if (localizer != null &&
    !string.IsNullOrEmpty(displayAttribute.Prompt) &&
    displayAttribute.ResourceType == null)
    {
    displayMetadata.Placeholder = () => localizer[displayAttribute.Prompt];
    }
    else
    {
    displayMetadata.Placeholder = () => displayAttribute.GetPrompt();
    }
    }
  7.   

												

本地化ASP.NET core模型绑定错误消息的更多相关文章

  1. 理解ASP.NET Core - 模型绑定&验证(Model Binding and Validation)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 模型绑定 什么是模型绑定?简单说就是将HTTP请求参数绑定到程序方法入参上,该变量可以是简单类 ...

  2. ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”

    DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMi ...

  3. ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”

    在<ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式>中,我们通过几个简单的实例演示了如何呈现一个错误页面,这些错误页面的呈现分别由三个对应的中间件来完成,接下来我们将 ...

  4. ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式

    由于ASP.NET Core应用是一个同时处理多个请求的服务器应用,所以在处理某个请求过程中抛出的异常并不会导致整个应用的终止.出于安全方面的考量,为了避免敏感信息的外泄,客户端在默认的情况下并不会得 ...

  5. ASP.NET MVC模型绑定的6个建议(转载)

    ASP.NET MVC模型绑定的6个建议 发表于2011-08-03 10:25| 来源博客园| 31 条评论| 作者冠军 validationasp.netmvc.netasp 摘要:ASP.NET ...

  6. ASP.NET没有魔法——ASP.NET MVC 模型绑定

    在My Blog中已经有了文章管理功能,可以发布和修改文章,但是对于文章内容来说,这里缺少最重要的排版功能,如果没有排版的博客很大程度上是无法阅读的,由于文章是通过浏览器查看的,所以文章的排版其实与网 ...

  7. ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(下篇)

    上一篇<ASP.NET没有魔法——ASP.NET MVC 模型绑定解析(上篇)>文章介绍了ASP.NET MVC模型绑定的相关组件和概念,本章将介绍Controller在执行时是如何通过这 ...

  8. [转] ASP.NET MVC 模型绑定的功能和问题

    摘要:本文将与你深入探究 ASP.NET MVC 模型绑定子系统的核心部分,展示模型绑定框架的每一层并提供扩展模型绑定逻辑以满足应用程序需求的各种方法. 同时,你还会看到一些经常被忽视的模型绑定技术, ...

  9. ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 异常和错误处理 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 异常和错误处理 上一章节中,我们学习了 ASP.NET Cor ...

随机推荐

  1. 解决webpack因新版本打包失败问题--ERROR in multi ./src/main.js ./dist/bundle.js

    最近在学习webpack打包过程中遇到的一个问题向大家分享下! 创建了一个webpacksty的目录,目录下放着dist,src子目录,然后通过node环境下,npm init -y 初始化项目出现p ...

  2. 关于无法解析的外部符号 _main

    今天在写一段代码的时候,遇到了这个问题,一般遇到这种问题,都是找不到主函数,就是main函数,可是我写的代码是有入口地址main函数的呀.最后发现是自己源文件里,main函数是.c文件,.h文件对应的 ...

  3. Windows注册表各个作用

    与注册表有关的术语1.注册表:是一个树状分层的数据库(如图).从物理上讲,它是System.dat和User.dat两个文件;从逻辑上讲,它是用户在注册表编辑器中看到的配置数据.2.HKEY :“根键 ...

  4. 如何使用安装光盘为本机创建yum repository

    在CentOS 6上可以使用系统安装光盘为本机创建yum repository,创建过程如下. 创建光盘mount点 [root@centos62 ~]# mkdir /media/CentOS mo ...

  5. DDD学习笔录——领域驱动设计的常见误区(即错误的理解)

    可以将DDD看成一种开发思想体系:它促成了一种新的以领域为中心的思维方式. 它是一种学习过程,而非最终目标,这就是DDD的最大优势. 任何团队都可以编写一个软件来满足一组用例的需求,但那些将时间和精力 ...

  6. Android指针管理:RefBase,SP,WP

    Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针.由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理. 要达到所有对象都可用引用计数器实现智能指针管 ...

  7. Consumer设计-high/low Level Consumer

    1 Producer和Consumer的数据推送拉取方式   Producer Producer通过主动Push的方式将消息发布到Broker n Consumer Consumer通过Pull从Br ...

  8. HDU 4912 LCA + 贪心

    题意及思路 说一下为什么按LCA深度从深到浅贪心是对的.我们可以直观感受一下,一条的路径会影响以这个lca为根的这颗树中的链,而深度越深,影响范围越小,所以先选影响范围小的路径. #include & ...

  9. SQL查询语句 [1]

    一.使用字符串作为条件查询 在 Home/controller/UserController.class.php 下插入 <?php namespace Home\Controller; use ...

  10. SQl Server Tsql基本编程 ,循环语句 ,存储过程

    一些比较重要但是不一定经常用的 句子 Tsql定义变量 declare @a int :  定义的变量前面必须用@,数据类型是SQL里的数据类型,执行的时候要把需要的有关联的代码一起执行,单独执行一条 ...