views:

764

answers:

4

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.MissingManifestResourceException: 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.

A: 

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.

Marvin Smit
Actually the files are fr-ca.resx and en-us.resx.Tho I tried to address them as you mentionned but as it is a website (not web application) there is no namespace/class. I even tried to move them to the App_Code to find them, didn't work more.
Erick
Hi Erick, if i remember correctly, if something doesn't have a namespace by itself, the ASP.Net JIT compiler will add the "ASP." as namespace.Easiest thing to do now is to compile your website (aspnet_compiler.exe) and load the resulting assemblies in Reflector. This will give you a clear insight on how your class is called.If you want to use the real ASP.Net libraries, you can look into the "c:\windows\Microsoft.Net\Framework\Temporary ASP.Net files\....\App_Code.9yopn1f7.dll"(Where the ... is a randomly generated directory by the Asp.Net JIT compiler hosted in IIS).
Marvin Smit
A: 

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.

Webleeuw
You have something you did not include. It is a website mode project. Therefore my resx (Locale.fr.resx in that case, is really Locale.fr.resx, only Xml files, no more no less). I don't have Designer file neither do I have namespaces. :)
Erick
I don't understand. How can you have no namespaces or designer files, but only resx files? Certainly when you work with C# as you say, you do have namespaces. Nevertheless, don't forget you'll need at least to create a Locale.resx (via the add new item option in the context menu of the solution explorer). Visual Studio should create a designer file behind your Locale.resx. The next step is to create localized resources for foreig languages.
Webleeuw
Please see my updated answer for more info over how a web project with localized resources could be set up.
Webleeuw
As stated previously, I do have a *website* note a *web application* :-) hence the difficulty. Otherwise it would be dead simple I would say :/
Erick
I asked on asp.net forums, it seems it is working *but* when I use ResourceManager.CreateResourceFromFile() it is seeking a ".resources" file instead of a ".resx" .... need to force it but no idea how
Erick
A: 

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&amp;OS=Windows%202003%20%20Service%20Pack%201
    Fr = &HC0C   'fr-CA http://www.microsoft.com/resources/msdn/goglobal/default.mspx?submitted=0C0C&amp;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"))
Fredou
Only usable as web application not web site... There is no namespace in website mode.
Erick
A: 

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

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

Elementenfresser