泉缘泉 发表于 2025-3-21 19:37:41

ASP.NET Core 模子验证消息的当地化新姿势

近来在研究系统当地化的问题,不可制止要实现模子类的验证消息当地化。毕竟这些错误消息是要返回给用户的。
疑问产生
在MVC模子下,我们会利用模子类对哀求参数进行绑定和验证。举个例子:
public class UserDto
{
   
    public string Name{get; set;}

   
   
    public int? Age {get; set; }

}这样本身没有什么问题,但如果有大量模子要做当地化改造,那可就是个大工程了。
我们不禁要问,为什么要指定ErrorMessage,默认的错误消息不能用吗?毕竟我们人工指定的错误消息除了字段名之外,别的都完全一样,着实没有必要逐个指定。
默认消息
我们来改造一下看看,删撤除指定的ErrorMessage。
public class UserDto
{
   
    public string Name{get; set;}

   
   
    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,证明我们的分析没错。
https://img2024.cnblogs.com/blog/777224/202503/777224-20250321165721826-1082022952.png
 
默认(中立语言)资源里面包含了错误消息,也包含了内部的非常消息。我们可以全部或者选择地当地化它们。
https://img2024.cnblogs.com/blog/777224/202503/777224-20250321170002718-864052792.png
 
 创建语言扩展包
我们创建一个项目,名为 FxResources.System.ComponentModel.Annotations。根据默认规则,在项目中创建的资源会自动添加命名空间作为前缀。
因此我们只必要再创建名为 SR 的资源即可。
https://img2024.cnblogs.com/blog/777224/202503/777224-20250321170730656-837239591.png
 如图,我们创建了对应的中文简体和中文繁体资源,这样就大功告成了!
https://img2024.cnblogs.com/blog/777224/202503/777224-20250321170935356-1542956857.png
说明:zh-Hans 兼容 zh-CN、zh-SG;zh-Hant 兼容 zh-TW、zh-MO、zh-HK。严格讲港澳台繁体略有差异,但在一般场景可以忽略。
 最终效果
同样是之前的例子,我们不必要再指定 ErrorMessage。
public class UserDto
{
   
    public string Name{get; set;}

   
   
    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 不同版本的资源之间有略微差异,各人选择对应的版本安装即可。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: ASP.NET Core 模子验证消息的当地化新姿势