【问题标题】:How to use ResourceManager in a "website" mode?如何在“网站”模式下使用 ResourceManager?
【发布时间】:2011-01-10 12:09:19
【问题描述】:

我正在尝试为我正在使用的应用程序进行手动翻译。 (已经有一个有效的 LocalizationModule 但它的工作很狡猾,所以我不能使用<asp:Localize /> 标签。

通常使用 ResourceManager 您应该将其用作Namespace.Folder.Resourcename(在应用程序中)。目前我正在翻译一个现有的 asp.net“网站”(不是 Web 应用程序,所以这里没有命名空间......)。

资源位于文件夹名称“Locales/resources”中,其中包含“fr-ca.resx”和“en-us.resx”。

所以我使用了类似这样的代码:

public static string T(string search)
 {
  System.Resources.ResourceManager resMan = new System.Resources.ResourceManager( "Locales", System.Reflection.Assembly.GetExecutingAssembly(), null );

  var text = resMan.GetString(search, System.Threading.Thread.CurrentThread.CurrentCulture);

  if (text == null)
   return "null";
  else if (text == string.Empty)
   return "empty";
  else
   return text;
 }

在页面内我有这样的东西<%= Locale.T("T_HOME") %>

当我刷新时,我有这个:

找不到任何资源 适用于指定的文化 或中立文化。确保 “Locales.resources”是正确的 嵌入或链接到程序集中 “App_Code.9yopn1f7”在编译时, 或者所有的卫星组件 required 是可加载且完全的 签。描述:一个未处理的 期间发生异常 执行当前的 Web 请求。 请查看堆栈跟踪以获取更多信息 有关错误和位置的信息 它起源于代码。

异常详情: System.Resources.MissingManifestResourceException: 找不到任何资源 适用于指定的文化 或中立文化。确保 “Locales.resources”是正确的 嵌入或链接到程序集中 “App_Code.9yopn1f7”在编译时, 或者所有的卫星组件 required 是可加载且完全的 签名。

来源错误:

第 14 行:
System.Resources.ResourceManager resMan = 新的 System.Resources.ResourceManager( “语言环境”, System.Reflection.Assembly.GetExecutingAssembly(), 空值 );第 15 行:第 16 行:var 文本 = resMan.GetString(搜索, System.Threading.Thread.CurrentThread.CurrentCulture); 第 17 行:第 18 行:if (text == null)

源文件: c:\inetpub\vhosts\galerieocarre.com\subdomains\dev\httpdocs\App_Code\Locale.cs 线路:16

我什至尝试使用 Locales.fr-ca 或仅使用 fr-ca 加载资源,这里没什么用。

【问题讨论】:

  • 是否可以将资源文件放在 App_LocalResources 文件夹中?
  • 这需要我为每个页面创建一个资源,我会说相当浪费时间:/ App_LocalResources 也主要用于 标签不是吗?

标签: c# asp.net localization web


【解决方案1】:

在 ASP.Net 中使用资源时,您会看到在 .resx 文件 (ResXCodeGen) 上使用了专门的编译器(自定义工具属性)

最重要的是你的资源被编译成一个类。此类的名称是您在处理其中的资源时应使用的名称。

类名生成如下:

{project namespace}{folder structure}{filename}.resx(.resx 不是生成名称的一部分)

由于您提到您的 resx 文件位于目录名称“Locales/resources”中,因此您必须使用的名称是(假设 resx 文件名为“locales.resx”)

“locales.resources.locales”

语言和区域设置的添加,如“uk-en”是由资源管理器添加的,根据创建 ResourceManager 实例时指定的文化加载适当的程序集。如果没有给出,则使用 Thread.CurrentCulture。您不应该自己使用语言/区域设置扩展,将其留给资源管理器来处理。

如果您不确定资源类将如何结束,您可以随时查看 MSIL 或使用反射器来确定实际部署程序集中的资源类的名称。

;--在放置的cmets之后添加-------

我还查看了一些其他代码;

您是否尝试过反思 App_GlobalResources 方法?

1:您在网站上下文中加载“App_GlobalResources”库(在 HttpHandler、Aspx、Ascx 等中)。 => Assembly.Load("App_GlobalResources");

2:浏览其中的可用类型并从每种类型中获取“ResourceManager”属性。=>

PropertyInfo pi = type.GetProperty("ResourceManager");

resManager = pi.GetValue(null, new object[] { }) as ResourceManager;

3:如果有,获取你想要的ResourceSet => resManager.GetResourceSet(englishCulture, true, true);

希望这会有所帮助。

【讨论】:

  • 其实文件是fr-ca.resx和en-us.resx。尽管我试图像您提到的那样解决它们,但由于它是一个网站(不是 Web 应用程序),因此没有命名空间/类。我什至尝试将它们移动到 App_Code 以找到它们,但没有更多工作。
  • 嗨,Erick,如果我没记错的话,如果某些东西本身没有命名空间,ASP.Net JIT 编译器将添加“ASP”。作为命名空间。现在最简单的事情是编译您的网站 (aspnet_compiler.exe) 并在 Reflector 中加载生成的程序集。这将使您清楚地了解您的课程是如何被调用的。如果你想使用真正的 ASP.Net 库,你可以查看“c:\windows\Microsoft.Net\Framework\Temporary ASP.Net files\....\App_Code.9yopn1f7.dll”(. .. 是托管在 IIS 中的 Asp.Net JIT 编译器随机生成的目录)。
【解决方案2】:

编辑

如果是网站项目,请阅读this walkthrough of Microsoft

恐怕你不能在网站项目中使用 ResourceMagager,因为它需要资源所在的命名空间/程序集。

【讨论】:

  • 你有一些你没有包括在内的东西。这是一个网站模式项目。因此我的 resx(Locale.fr.resx 在这种情况下,实际上是 Locale.fr.resx,只有 Xml 文件,不多不少)。我没有 Designer 文件,也没有命名空间。 :)
  • 我不明白。怎么可能没有命名空间或设计器文件,而只有 resx 文件?当然,当您使用 C# 时,您确实有命名空间。尽管如此,不要忘记您至少需要创建一个 Locale.resx(通过解决方案资源管理器的上下文菜单中的添加新项目选项)。 Visual Studio 应该在您的 Locale.resx 后面创建一个设计器文件。下一步是为外语创建本地化资源。
  • 请查看我的更新答案,了解有关如何设置具有本地化资源的 Web 项目的更多信息。
  • 如前所述,我确实有一个 网站 注意一个 web 应用程序 :-) 因此困难。否则我会说这很简单:/
  • 我在 asp.net 论坛上问过,它似乎在工作但是当我使用 ResourceManager.CreateResourceFromFile() 时,它正在寻找“.resources”文件而不是“ .resx" ....需要强制但不知道如何
【解决方案3】:

这不是 c#,但您可以轻松地将其转换为它

我在 app_localResources 目录中有 2 个文件

myPage.aspx.resx
myPage.aspx.fr-ca.resx

我在我的 .aspx 页面中这样使用它

<asp:Label ID="lAddress1" runat="server" Text="<%$ Resources: lAddress1 %>"></asp:Label>

这就是我的管理方式

'using LCID from 
Public Enum elang
    En = &H1009  'en-CA http://www.microsoft.com/resources/msdn/goglobal/default.mspx?submitted=1009&OS=Windows%202003%20%20Service%20Pack%201
    Fr = &HC0C   'fr-CA http://www.microsoft.com/resources/msdn/goglobal/default.mspx?submitted=0C0C&OS=Windows%202003%20%20Service%20Pack%201
End Enum

'strongly typed value in session
Private _lang As elang = elang.En
Public Property lang() As elang
    Get
        Return _lang
    End Get
    Set(ByVal value As elang)
        _lang = value
    End Set
End Property

在我得到的每一页中

Protected Overrides Sub InitializeCulture()
    If Not Me.IsPostBack Then
        Threading.Thread.CurrentThread.CurrentUICulture = New Globalization.CultureInfo(Sess.lang)
        Threading.Thread.CurrentThread.CurrentCulture = Globalization.CultureInfo.CreateSpecificCulture(Threading.Thread.CurrentThread.CurrentUICulture.Name)
    End If
    MyBase.InitializeCulture()
End Sub

当我想使用资源管理器时,我在根级别创建了一个全局资源文件,我像这样使用它

Dim rm = New System.Resources.ResourceManager("Resources.MyPage", Reflection.Assembly.Load("App_GlobalResources"))

【讨论】:

  • 仅可用作 Web 应用程序而不是网站...网站模式下没有命名空间。
【解决方案4】:

也许您只是在寻找 System.Web.Page 的基础 GetLocalResourceObject(),

http://msdn.microsoft.com/en-us/library/ms153597.aspx

【讨论】:

  • 非常感谢您的回答,我搜索了很多页面,这在我的“网站”中对我有用。在页面中简单地说GetGlobalResourceObject("ResourceFileName", "String1")
【解决方案5】:

如果您无权访问 HTTPContext,Marvin Smit 的解决方案非常棒

const string ASSEMBLY_NAME = "App_GlobalResources";
const string RESOURCE_NAME = "Resources.MetaTagResource";
const string RESOURCE_MANAGER = "ResourceManager";

Assembly assembly = Assembly.Load(ASSEMBLY_NAME);
Type type = assembly.GetType(RESOURCE_NAME);
PropertyInfo propertyInfo = type.GetProperty(RESOURCE_MANAGER);
ResourceManager resourceManager = propertyInfo.GetValue(null, new object[] { }) as ResourceManager;
resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true);

但如果您有权访问 HTTPContext,只需使用 HttpContext.GetGlobalResourceObject

string title = HttpContext.GetGlobalResourceObject("MetaTagResource", "Title").ToString();
string keywords = HttpContext.GetGlobalResourceObject("MetaTagResource", "keywords").ToString();
string description = HttpContext.GetGlobalResourceObject("MetaTagResource", "Description").ToString();

【讨论】:

  • return (string) HttpContext.GetGlobalResourceObject( "Resources.SiteTxt", name, GetCultureFromLanguage() );也为我做了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 2022-09-06
  • 2020-09-14
  • 2015-07-30
  • 1970-01-01
相关资源
最近更新 更多