最近在研究系统本地化的问题,不可避免要实现模型类的验证消息本地化。毕竟这些错误消息是要返回给用户的。

疑问产生

在MVC模型下,我们会使用模型类对请求参数进行绑定和验证。举个例子:

public class UserDto
{
[Required(ErrorMessage = "姓名不能为空")]
public string Name{get; set;} [Required(ErrorMessage = "年龄不能为空")]
[Range(1, 120, ErrorMessage = "年龄必须在1到120之间")]
public int? Age {get; set; } }

这样本身没有什么问题,但如果有大量模型要做本地化改造,那可就是个大工程了。

我们不禁要问,为什么要指定ErrorMessage,默认的错误消息不能用吗?毕竟我们人工指定的错误消息除了字段名之外,其它都完全一样,实在没有必要逐个指定。

默认消息

我们来改造一下看看,删除掉指定的ErrorMessage。

public class UserDto
{
[Required]
public string Name{get; set;} [Required]
[Range(1, 120)]
public int? Age {get; set; } }

如果没有传入参数导致验证不通过,会得到如下消息:

"The Name field is required."
"The Age field is required."

没错,默认消息是英文的,这对我们来说完全不可用——这对用户很不友好,难怪要人工设置 ErrorMessage。

查找默认消息

那有没有可能直接把默认消息本地化呢?如果可以,那就不用再麻烦地设置 ErrorMessage了。

通过查看官方源码我们发现,默认消息来自 SR 类,以RequiredAttribute举例:

public RequiredAttribute()
: base(() => SR.RequiredAttribute_ValidationError)
{
}

SR 类的内容简略如下:

internal static partial class SR
{
internal static global::System.Resources.ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new global::System.Resources.ResourceManager(typeof(FxResources.System.ComponentModel.Annotations.SR))); internal static string @RequiredAttribute_ValidationError => GetResourceString("RequiredAttribute_ValidationError", @"The {0} field is required.");
}

上面的代码中,GetResourceString 最终会调用内部声明的 ResourceManager。而 ResourceManager 会根据传入的类型参数查找本地化资源。

本地化默认消息

通过上面的分析,如果要使用中文内容,我们只要把本地化的消息放入 FxResources.System.ComponentModel.Annotations.SR.zh-CN.resources 即可。动手之前,我们再确认一下。

ILSpy 打开 System.ComponentModel.Annotations.dll,确实可以看到默认的资源 FxResources.System.ComponentModel.Annotations.SR.resources,证明我们的分析没错。

默认(中立语言)资源里面包含了错误消息,也包含了内部的异常消息。我们可以全部或者选择地本地化它们。

建立语言扩展包

我们建立一个项目,名为 FxResources.System.ComponentModel.Annotations。根据默认规则,在项目中建立的资源会自动添加命名空间作为前缀。

因此我们只需要再创建名为 SR 的资源即可。

如图,我们建立了对应的中文简体中文繁体资源,这样就大功告成了!

说明:zh-Hans 兼容 zh-CN、zh-SG;zh-Hant 兼容 zh-TW、zh-MO、zh-HK。严格讲港澳台繁体略有差异,但在一般场景可以忽略。

 最终效果

同样是之前的例子,我们不需要再指定 ErrorMessage。

public class UserDto
{
[Required]
public string Name{get; set;} [Required]
[Range(1, 120)]
public int? Age {get; set; } }

现在我们得到的消息是这样,看起来还不错。

"Name 字段为必填项。"
"Age 字段为必填项。"

注意:如果你的项目没有启用国际化功能,你需要设置默认的文化为中文:CultureInfo.DefaultThreadUICulture = CultureInfo.GetCultureInfo("zh-Hans")

Nuget 包

为方便大家使用,已经将语言资源打包为语言包,大家直接安装到项目即可。

Install-Package FxResources.System.ComponentModel.Annotations.zh-Hans -Version 9.0.0

.NET 不同版本的资源之间有略微差异,大家选择对应的版本安装即可。

ASP.NET Core 模型验证消息的本地化新姿势的更多相关文章

  1. ASP.NET Core 模型验证的一个小小坑

    今天在我们的一个项目中遇到一个 asp.net core 模型验证(model validation)的小问题.当模型属性的类型是 bool ,而提交上来的该属性值是 null ,asp.net co ...

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

    默认错误消息: MissingBindRequiredValueAccessor A value for the '{0}' property was not provided. MissingKey ...

  3. ASP.NET MVC - 模型验证

    ASP.NET MVC - 模型验证(Model verification) 模型验证原理浅析 模型验证用到了模型绑定器.模型验证器(System.Web.Mvc.DataAnnotationsMod ...

  4. ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 验证特性 上一章节我们简单介绍了 ...

  5. asp.net mvc 模型验证组件——FluentValidation

    asp.net mvc 模型验证组件——FluentValidation 示例 using FluentValidation; public class CustomerValidator: Abst ...

  6. ASP.NET与ASP.NET Core用户验证Cookie并存解决方案

    在你将现有的用户登录(Sign In)站点从ASP.NET迁移至ASP.NET Core时,你将面临这样一个问题——如何让ASP.NET与ASP.NET Core用户验证Cookie并存,让ASP.N ...

  7. ASP.NET Core身份验证

    asp.net core 身份验证 本文旨在演示如果使用内置的 identity 实现 asp.net core 的身份验证,不会进行其它扩展.本文将通过最简单的代码演示如何进行登录和身份验证操作. ...

  8. 学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

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

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

  10. Asp.Net Core 客户端验证和远程验证

    我们先来看这样一个注册页面和它的后台Model @model RegisterViewModel @{ ViewBag.Title = "用户注册"; } <h1>用户 ...

随机推荐

  1. Docker简易操作

    Docker简易操作 1.启动docker sudo docker run [OPTIONS] IMAGE [COMMAND] [ARG...] sudo docker run -d -p 8009: ...

  2. Mac terminal proxy

    cat >> ~/.bash_profile << EOF function proxy_on() { export http_proxy=http://127.0.0.1:7 ...

  3. biancheng-Spring Boot框架

    目录http://c.biancheng.net/spring_boot/ 1Spring Boot是什么2创建Spring Boot项目3Spring Boot starter4YAML5Sprin ...

  4. 未能加载文件或程序集"Symtem.Data.SQLite.dll"或它的某一个依赖项

    我在window service 2016 等更高版本的服务器上遇见过,普通window系统未预见.可尝试安装 VC ++ 2010 我下载安装  之后就好了.

  5. Practical Secure Aggregation for Privacy-Preserving Machine Learning

    1 介绍 本文是谷歌团队发在CCS2017上的文章,旨在解决联邦学习中安全聚合的问题. 安全聚合:多方参与者将信息传递给聚合者,聚合者除了知道这个信息的总和不能知道任何一个特定参与者的信息. 在这篇文 ...

  6. OA系统的天数该怎样计算

    文章首发:https://blog.liuzijian.com/post/oa-system-count-days.html 在开发一些OA系统的过程中,经常能遇到一个问题,就是时长计算,比如请假有请 ...

  7. 记录一次修复 JetBrains Rider 控制台输出乱码

    在使用 JetBrains Rider 调试程序时,控制台输出日志出现了乱码. 歪打正着结果困扰许久的问题得到了解决,于是记录下了这个小短文. 具体的修复建议如下:将终端编码设置为 GB2312 具体 ...

  8. IGM机器人维修的关键环节

    在现代科技领域,机器人已经成为不可或缺的一部分,它们广泛应用于各个行业,包括制造业.服务业.医疗.科研等.对于任何机器人来说,定期的维护和修理都是必不可少的.这不仅可以确保机器人正常工作,还可以延长其 ...

  9. 库卡机器人KR3R540电源模块常见故障维修解决方法

            库卡机器人KR3R540电源模块的常见故障及维修解决方法包括:           电源模块无法正常启动:应检查电源模块的电源连接是否正常,以及电源开关是否开启.如果电源连接正常,但驱 ...

  10. QT5笔记:12. 字符串和数值之间的转换

    字符串与进制转换的例子 /** * @brief Widget::on_btnCalcHex_clicked 从界面上获取十六进制字符串,然后转为十进制和二进制字符串写回界面 */ void Widg ...