c# - 序列化时如何本地化类属性?
问题描述
我正在开发一个 asp.net core 5 web api 项目,我想在序列化并将其转换为 json 时本地化(翻译)我的 DTO 属性。例如假设我们有这个类:
public class PersonDto
{
public string Name { get; set; }
public int Grade { get; set; }
}
所以当我尝试序列化这个对象时,JsonConvert.Serialize(personDto)
我得到了一个像这样的 json:
{
"name": "any name",
"grade": 90
}
但是当用户发送Accept-Language: fr-FR
标头时,我想返回如下响应:
{
"nom": "any name",
"classe": 90
}
(我不懂法语,我只是用谷歌翻译来证明我的目的。)
到目前为止我所做的:
首先,我在我的项目中添加了本地化。这是配置:
services.AddLocalization();
services.Configure<RequestLocalizationOptions>(
options =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en-US"),
new CultureInfo("fr-FR")
};
options.DefaultRequestCulture = new RequestCulture(culture: "fr-FR", uiCulture: "fr-FR");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new[] { new AcceptLanguageHeaderRequestCultureProvider() };
});
对于启动的配置部分:
// ..
app.UseRouting();
app.UseRequestLocalization();
// ..
并且本地化在我刚刚写的TestContoller中工作:
public class Test : BaseController // BaseController is inherited from ControllerBase (it's OK)
{
private readonly IStringLocalizer<Resource> _localizer;
public Test(IStringLocalizer<Resource> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer.GetString("Hello");
}
}
因此,当我们发送Accept-Language: fr-FR
标头时,我们会得到Bonjour作为响应,这没关系。
但我不知道如何翻译类属性。我尝试编写一个CustomContractResolver并且它工作但它有一个错误。这是ContractResolver:
public class CustomContractResolver : DefaultContractResolver
{
private readonly HashSet<Type> _localizeds;
private readonly IStringLocalizer<Resource> _localizer;
public CustomContractResolver(IStringLocalizer<Resource> localizer)
{
_localizer = localizer;
_localizeds = new HashSet<Type>();
}
public void Localize(Type type)
{
if (!_localizeds.Contains(type))
_localizeds.Add(type);
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (IsLocalized(property.DeclaringType, property.PropertyName))
{
property.PropertyName = _localizer.GetString(property.PropertyName);
}
return property;
}
private bool IsLocalized(Type type, string jsonPropertyName)
{
if (!_localizeds.Contains(type))
return false;
return type.GetProperties().Any(p => p.Name.Equals(jsonPropertyName));
}
}
我通过在启动的配置方法中JsonDefaultSettings
调用它来添加它:app.ChangePropertyNameForLocalizableClasses();
public static class NewtonsoftJsonOptionsExtensions
{
public static void ChangePropertyNameForLocalizableClasses(this IApplicationBuilder app)
{
// CustomLocalizeAttribute is a custom attribute that I add to classes that I want to localize them when serializng
// We are using reflection to get all the classes that should be localized when serializing
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(c => c.HasAttribute<CustomLocalizeAttribute>() && !c.IsAbstract && c.IsPublic && c.IsClass);
// Our problem starts here: I have to inject localizer manually and DI isn't working
var localizer = app.ApplicationServices.GetRequiredService<IStringLocalizer<Resource>>();
var jsonResolver = new PropertyRenameAndIgnoreSerializerContractResolver(localizer);
foreach (var type in types)
{
jsonResolver.Localize(type);
}
JsonConvert.DefaultSettings = () =>
{
var settings = new JsonSerializerSettings {ContractResolver = jsonResolver};
return settings;
};
}
}
所以我的问题是当程序启动时,如果第一个请求具有Accept-Language: fr-FR
标头,那么所有具有的类CustomLocalizeAttribute
在序列化时都将被本地化,并且它们忽略了Accept-Language
标头实际上是什么。
如何_localizer
在每个请求中获取 (IStringLocalizer) 的新实例?
也许我一路走错!这是一项常见的任务吗?还有其他解决方案吗?
解决方案
推荐阅读
- mysql - 如何从 SQL Server 中特定数据库的表中获取所有列名?
- c# - 如何使用 C# 读取 GAEB 文件
- flutter - 字段“位置”尚未初始化
- nuxt.js - 如何使用 Nuxt.js 和 Nuxt Content 无头 CMS 向静态站点添加搜索功能
- python - 如何在带有 pybricks (micropython) 的 VSC 中使用 Intellisense?
- javascript - 将变量传递给 javascript 正则表达式
- google-apps-script - TextStartsWith 时更改行对齐 - Google 表格脚本
- reactjs - 'FunctionComponent 类型上不存在属性 Y
' 即使接口包含属性 Y - react-navigation - React 导航仅在主屏幕上显示选项卡
- c# - ASP .NET Core 日志记录 API 是否具有创建类似于 Serilog“ForContext”方法的独立记录器的方法?