.NET Framework的ModelMetadataProvider在.NET Core的等效方案及多语言问题
.NET 6中替代ModelMetadataProvider获取本地化DisplayName的方案
在.NET 6中,你可以使用**IModelMetadataProvider接口及其默认实现DefaultModelMetadataProvider**来替代.NET Framework中的ModelMetadataProvider,它能自动处理DisplayAttribute的本地化资源切换,解决TypeDescriptor缓存资源值导致Culture切换不生效的问题。
实现步骤与代码示例
1. 依赖准备
ASP.NET Core项目默认已包含Microsoft.AspNetCore.Mvc.Core包(该包提供了IModelMetadataProvider和DefaultModelMetadataProvider),非ASP.NET Core项目可手动安装此NuGet包。
2. 依赖注入方式(推荐,适用于服务/控制器场景)
通过构造函数注入IModelMetadataProvider,直接调用方法获取本地化DisplayName:
// 示例服务类 public class DisplayNameService { private readonly IModelMetadataProvider _metadataProvider; // 构造函数注入IModelMetadataProvider public DisplayNameService(IModelMetadataProvider metadataProvider) { _metadataProvider = metadataProvider; } public string GetLocalizedPropertyDisplayName(Type classType, string propertyName) { var propertyMetadata = _metadataProvider.GetMetadataForProperty(classType, propertyName); return propertyMetadata.DisplayName; } } // 调用示例 var service = serviceProvider.GetRequiredService<DisplayNameService>(); string displayName = service.GetLocalizedPropertyDisplayName(typeof(SampleClass), "Name");
3. 手动实例化方式(适用于非DI场景)
如果无法使用依赖注入,可手动创建DefaultModelMetadataProvider实例:
using Microsoft.AspNetCore.Mvc.ModelMetadata; using Microsoft.AspNetCore.Mvc.ModelMetadata.Internal; // 创建元数据提供器实例 var metadataProvider = new DefaultModelMetadataProvider( new EmptyModelMetadataProvider(), new DefaultModelMetadataDetailsProvider( new IMetadataDetailsProvider[] { new DisplayMetadataProvider() })); // 获取本地化DisplayName Type classType = typeof(SampleClass); string propertyName = "Name"; var propertyMetadata = metadataProvider.GetMetadataForProperty(classType, propertyName); string displayName = propertyMetadata.DisplayName;
4. 切换CultureInfo的示例
确保当前线程的Culture设置正确,DefaultModelMetadataProvider会自动读取对应语言的资源:
// 切换到中文简体 CultureInfo.CurrentCulture = new CultureInfo("zh-CN"); CultureInfo.CurrentUICulture = new CultureInfo("zh-CN"); // 重新获取DisplayName即可得到本地化后的值 string localizedName = metadataProvider.GetMetadataForProperty(typeof(SampleClass), "Name").DisplayName;
方案优势
- 完全兼容.NET Framework中
ModelMetadataProvider的行为,支持DisplayAttribute的ResourceType参数。 - 每次获取DisplayName时都会根据当前
CultureInfo重新读取资源,不会缓存静态值,解决了TypeDescriptor的本地化失效问题。
内容的提问来源于stack exchange,提问作者Akbar Taghipour
相关产品推荐
相关产品推荐

