ASP.NET MVC 以编程方式检索本地化资源
ASP.NET MVC Retrieve localized resources programmatically
我有一个 HTTP 处理程序,它读取 ASP.NET MVC 程序集中的所有资源文件并将它们转换为 Javascript 对象。除了 1 个相当大的细节外,代码运行良好,因为我需要能够预定义文化。我不能使用有用的网络配置的自动 UI 文化,而是我想使用数据库配置。这段代码一运行,它仍然采用我计算机的本地文化。有没有办法设置文化?我正在考虑使用 ResourceManager,但我没有这样做。
public void ProcessRequest(HttpContext context)
{
// Check current assembly
Assembly currentAssembly = null;
Type appType = HttpContext.Current.ApplicationInstance.GetType();
if (appType.Namespace == "ASP")
{
currentAssembly = appType.BaseType.Assembly;
}
else
{
currentAssembly = appType.Assembly;
}
// Get resource files in this assembly, in this cased reference by Resources namespace
IEnumerable<Type> resources = currentAssembly.GetTypes().Where(x => x.Namespace == "Resources");
// Generate Javascript namespace through which each resource file will be referenced
context.Response.ContentType = "text/javascript";
context.Response.Write("var Resources = {};\n");
foreach (Type resource in resources)
{
// For each type, add an object to the namespace
context.Response.Write(string.Format("Resources.{0} = {{}};\n", resource.Name));
// Get all resource keys and values for every resource file
IDictionary<String, String> resourceKeyValues =
resource
.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.GetProperty)
.Where(x => x.PropertyType == typeof(string))
.ToDictionary(x => x.Name, x => x.GetValue(null, null).ToString());
// Include each key + value
foreach (String key in resourceKeyValues.Keys)
{
context.Response.Write(string.Format("Resources.{0}.{1} = '{2}';\n", resource.Name, key, resourceKeyValues[key].Replace("'", "\'")));
}
}
}
我设法将两种方法与请求的结果结合起来。最初我的代码基于 this article and ignored Rick Strahl's approach. Due to this issue, I investigated his article into greater depth and came across this 文章。
这是我想出的:
public void ProcessRequest(HttpContext context)
{
// Check current assembly
Assembly currentAssembly = null;
Type appType = HttpContext.Current.ApplicationInstance.GetType();
if (appType.Namespace == "ASP")
{
currentAssembly = appType.BaseType.Assembly;
}
else
{
currentAssembly = appType.Assembly;
}
ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
string language = claimsIdentity.FindFirst(ClaimTypes.Locality).Value;
CultureInfo requestedCulture = new CultureInfo(language);
// Get resource files in this assembly, in this cased reference by Resources namespace
IEnumerable<Type> resources = currentAssembly.GetTypes().Where(x => x.Namespace == "Resources");
context.Response.ContentType = "text/javascript";
context.Response.Write("var Resources = {};\n");
foreach (Type resource in resources)
{
// For each type, add an object to the namespace
context.Response.Write(string.Format("Resources.{0} = {{}};\n", resource.Name));
Dictionary<object, object> dictionary = this.ReadResources(resource.Name, requestedCulture);
foreach (KeyValuePair<object, object> key in dictionary)
{
context.Response.Write(string.Format("Resources.{0}.{1} = '{2}';\n", resource.Name, key.Key, key.Value.ToString().Replace("'", "\'")));
}
}
}
private Dictionary<object, object> ReadResources(string classKey, CultureInfo requestedCulture)
{
var resourceManager = new ResourceManager("Resources." + classKey, Assembly.Load("App_GlobalResources"));
using (var resourceSet = resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true))
{
return resourceSet.Cast<DictionaryEntry>().ToDictionary(x => x.Key, x => resourceManager.GetObject((string)x.Key, requestedCulture));
}
}
我有一个 HTTP 处理程序,它读取 ASP.NET MVC 程序集中的所有资源文件并将它们转换为 Javascript 对象。除了 1 个相当大的细节外,代码运行良好,因为我需要能够预定义文化。我不能使用有用的网络配置的自动 UI 文化,而是我想使用数据库配置。这段代码一运行,它仍然采用我计算机的本地文化。有没有办法设置文化?我正在考虑使用 ResourceManager,但我没有这样做。
public void ProcessRequest(HttpContext context)
{
// Check current assembly
Assembly currentAssembly = null;
Type appType = HttpContext.Current.ApplicationInstance.GetType();
if (appType.Namespace == "ASP")
{
currentAssembly = appType.BaseType.Assembly;
}
else
{
currentAssembly = appType.Assembly;
}
// Get resource files in this assembly, in this cased reference by Resources namespace
IEnumerable<Type> resources = currentAssembly.GetTypes().Where(x => x.Namespace == "Resources");
// Generate Javascript namespace through which each resource file will be referenced
context.Response.ContentType = "text/javascript";
context.Response.Write("var Resources = {};\n");
foreach (Type resource in resources)
{
// For each type, add an object to the namespace
context.Response.Write(string.Format("Resources.{0} = {{}};\n", resource.Name));
// Get all resource keys and values for every resource file
IDictionary<String, String> resourceKeyValues =
resource
.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.GetProperty)
.Where(x => x.PropertyType == typeof(string))
.ToDictionary(x => x.Name, x => x.GetValue(null, null).ToString());
// Include each key + value
foreach (String key in resourceKeyValues.Keys)
{
context.Response.Write(string.Format("Resources.{0}.{1} = '{2}';\n", resource.Name, key, resourceKeyValues[key].Replace("'", "\'")));
}
}
}
我设法将两种方法与请求的结果结合起来。最初我的代码基于 this article and ignored Rick Strahl's approach. Due to this issue, I investigated his article into greater depth and came across this 文章。
这是我想出的:
public void ProcessRequest(HttpContext context)
{
// Check current assembly
Assembly currentAssembly = null;
Type appType = HttpContext.Current.ApplicationInstance.GetType();
if (appType.Namespace == "ASP")
{
currentAssembly = appType.BaseType.Assembly;
}
else
{
currentAssembly = appType.Assembly;
}
ClaimsIdentity claimsIdentity = (ClaimsIdentity)HttpContext.Current.User.Identity;
string language = claimsIdentity.FindFirst(ClaimTypes.Locality).Value;
CultureInfo requestedCulture = new CultureInfo(language);
// Get resource files in this assembly, in this cased reference by Resources namespace
IEnumerable<Type> resources = currentAssembly.GetTypes().Where(x => x.Namespace == "Resources");
context.Response.ContentType = "text/javascript";
context.Response.Write("var Resources = {};\n");
foreach (Type resource in resources)
{
// For each type, add an object to the namespace
context.Response.Write(string.Format("Resources.{0} = {{}};\n", resource.Name));
Dictionary<object, object> dictionary = this.ReadResources(resource.Name, requestedCulture);
foreach (KeyValuePair<object, object> key in dictionary)
{
context.Response.Write(string.Format("Resources.{0}.{1} = '{2}';\n", resource.Name, key.Key, key.Value.ToString().Replace("'", "\'")));
}
}
}
private Dictionary<object, object> ReadResources(string classKey, CultureInfo requestedCulture)
{
var resourceManager = new ResourceManager("Resources." + classKey, Assembly.Load("App_GlobalResources"));
using (var resourceSet = resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true))
{
return resourceSet.Cast<DictionaryEntry>().ToDictionary(x => x.Key, x => resourceManager.GetObject((string)x.Key, requestedCulture));
}
}