ASP.NET Core 模型验证消息的本地化新姿势
最近在研究系统本地化的问题,不可避免要实现模型类的验证消息本地化。毕竟这些错误消息是要返回给用户的。
疑问产生
在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 模型验证消息的本地化新姿势的更多相关文章
- ASP.NET Core 模型验证的一个小小坑
今天在我们的一个项目中遇到一个 asp.net core 模型验证(model validation)的小问题.当模型属性的类型是 bool ,而提交上来的该属性值是 null ,asp.net co ...
- 本地化ASP.NET core模型绑定错误消息
默认错误消息: MissingBindRequiredValueAccessor A value for the '{0}' property was not provided. MissingKey ...
- ASP.NET MVC - 模型验证
ASP.NET MVC - 模型验证(Model verification) 模型验证原理浅析 模型验证用到了模型绑定器.模型验证器(System.Web.Mvc.DataAnnotationsMod ...
- ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Identity 验证特性 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Identity 验证特性 上一章节我们简单介绍了 ...
- asp.net mvc 模型验证组件——FluentValidation
asp.net mvc 模型验证组件——FluentValidation 示例 using FluentValidation; public class CustomerValidator: Abst ...
- ASP.NET与ASP.NET Core用户验证Cookie并存解决方案
在你将现有的用户登录(Sign In)站点从ASP.NET迁移至ASP.NET Core时,你将面临这样一个问题——如何让ASP.NET与ASP.NET Core用户验证Cookie并存,让ASP.N ...
- ASP.NET Core身份验证
asp.net core 身份验证 本文旨在演示如果使用内置的 identity 实现 asp.net core 的身份验证,不会进行其它扩展.本文将通过最简单的代码演示如何进行登录和身份验证操作. ...
- 学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 理解ASP.NET Core - 模型绑定&验证(Model Binding and Validation)
注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 模型绑定 什么是模型绑定?简单说就是将HTTP请求参数绑定到程序方法入参上,该变量可以是简单类 ...
- Asp.Net Core 客户端验证和远程验证
我们先来看这样一个注册页面和它的后台Model @model RegisterViewModel @{ ViewBag.Title = "用户注册"; } <h1>用户 ...
随机推荐
- 特殊数据类型的深度分析:JSON、数组和 HSTORE 的实用价值
title: 特殊数据类型的深度分析:JSON.数组和 HSTORE 的实用价值 date: 2025/1/4 updated: 2025/1/4 author: cmdragon excerpt: ...
- HashMap源码解析-JDK18
引言 HashMap在JDK1.8和1.7中差异较大,在JDK1.8中HashMap引入了红黑树,优化减少了哈希冲突,提高了哈希表的存取效率. 本篇文章分析的就是JDK1.8中的HashMap源码. ...
- 深入解析 Spring AI 系列:剖析OpenAI接口接入组件
今天我们将继续探讨如何在Spring AI中接入大语言模型,以OpenAI为例,详细分析其接入过程.我们将逐步探讨OpenAI是如何与Spring AI系统对接的,具体包括如何配置接口.如何封装接口参 ...
- h5 页面播放base64编码的audio数据
例子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- Android平台架构及特性
Android平台架构及特性 Android系统的底层是建立在Linux系统之上,改平台由操作系统.中间件.用户界面和应用软件四层组成,它采用一种被称为软件叠层(Software Stack)的方式进 ...
- springboot-总结列表
一.Spring Boot 具有以下特点: 1. 独立运行的 Spring 项目 Spring Boot 可以以 jar 包的形式独立运行,Spring Boot 项目只需通过命令" jav ...
- RSA的原理和简单实践
RSA加密是一种非对称加密,原理是: 使⽤算法可以⽣成两把钥匙 A 和 B 使⽤ A 加密的信息,使⽤ B 可以解开 使⽤ B 加密的信息,使⽤ A 可以解开 ⽇常使⽤中,我们把⼀把作为公钥公开发布. ...
- C#/.NET/.NET Core技术前沿周刊 | 第 22 期(2025年1.13-1.19)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- CDN在互联网直播中的运用与性能优化
本文分享自天翼云开发者社区<CDN在互联网直播中的运用与性能优化>,作者:不知不觉 随着互联网技术的不断发展,互联网直播已成为人们获取信息.娱乐.学习等多种需求的重要途径之一.然而,在直播 ...
- Kali 修改root密码
Kali 修改root密码 进入 Kali 系统,切换 root 用户 sudo su 输入当前用户密码 成功切换到 root 用户后,进行修改密码 passwd root