开发者

How to use ResourceManager in a "website" mode?

I am trying here to do a manual translation for the application I am working with. (There is already a working LocalizationModule but it's working dodgy, so I can't use <asp:Localize /> tags.

Normally with ResourceManager you are supposed to be using it as Namespace.Folder.Resourcename (in an application). Currently I am translating an existing asp.net "website" (not web application so no namespace here....).

The resources are located into a folder name "Locales/resources" which contains "fr-ca.resx" and "en-us.resx".

So I used a code with something like this :

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;
 }

and inside the page I have something like this <%= Locale.T("T_HOME") %>

When I refresh I have this :

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Locales.resources" was correctly embedded or linked into assembly "App_Code.9yopn1f7" at compile time, or that all the satellite assemblies required are loadable and fully signed. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Resources.MissingManifestResourceEx开发者_如何学Pythonception: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Locales.resources" was correctly embedded or linked into assembly "App_Code.9yopn1f7" at compile time, or that all the satellite assemblies required are loadable and fully signed.

Source Error:

Line 14:

System.Resources.ResourceManager resMan = new System.Resources.ResourceManager( "Locales", System.Reflection.Assembly.GetExecutingAssembly(), null ); Line 15: Line 16: var text = resMan.GetString(search, System.Threading.Thread.CurrentThread.CurrentCulture); Line 17: Line 18: if (text == null)

Source File: c:\inetpub\vhosts\galerieocarre.com\subdomains\dev\httpdocs\App_Code\Locale.cs Line: 16

I even tried to load the resource with Locales.fr-ca or only fr-ca nothing quite work here.


Marvin Smit's solution is great if you do not have access to the HTTPContext

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);

But if you have access to the HTTPContext just use HttpContext.GetGlobalResourceObject

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


Maybe you are just looking for The System.Web.Page's base GetLocalResourceObject(),?

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


When using resources in ASP.Net, you will see a specialized compiler being used (custom Tool property) on the .resx files (ResXCodeGen)

Bottom line of this is that your resources are compiled into a class. The name of this class is the name you should use when you want to address the resources in there.

The name of the class is generated as follows:

{project namespace}{folder structure}{filename}.resx (.resx is NOT part of the generated name)

Since you mentioned your resx file is located in a directory name "Locales/resources", the name you would have to use is (assuming the resx file is called 'locales.resx')

"locales.resources.locales"

The addition of the language and locale, like the "uk-en" is added by the resource manager, loading the appropriate assembly based on the Culture that is specified when creating an instance of the ResourceManager. If none is given, the Thread.CurrentCulture is used. You should not use the language/locale extensions yourself, leave it to the resource manager to deal with that.

If you are not sure how the resources class will end up, you can always look at the MSIL or use reflector to determine the name of the resource class in the actual deployed assembly.

;-- Added after comments where placed -------

I also looked at some other code i had arround;

Have you tried the Reflection on App_GlobalResources approach?

1: You load the "App_GlobalResources" library while in the context of the website (in a HttpHandler, Aspx, Ascx, etc). => Assembly.Load("App_GlobalResources");

2: Walk through the available types in there and grab the "ResourceManager" property from each type.=>

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

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

3: If it had one, get the ResourceSet you want => resManager.GetResourceSet(englishCulture, true, true);

Hope this helps.


this is not c# but you can easily convert it into it

I have in the app_localResources directory with 2 files

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

and I use it like this in my .aspx page

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

this is how I manage it on mine

'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

and in every page I got

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

when I want to use the resourcemanager I create a global resources file at the root level the I use it like this

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


Edit

In case of a Web Site project, read this walkthrough of Microsoft.

I'm afraid you can't use the ResourceMagager in a Website project, because it requires a namespace / assembly where the resources are located.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜