开发者

CurrentThread.CurrentUICulture is set correctly but seems to be ignored by asp.net

开发者 https://www.devze.com 2023-03-01 11:05 出处:网络
Im struggling with gettings the values from the correct strings.txt in my resource files in my \\bin folder when switching languages.

Im struggling with gettings the values from the correct strings.txt in my resource files in my \bin folder when switching languages.

I have a domain.com (for English) and a domain.nl (for Dutch). It however doesnt seem to matter which domain I use and how I set the currentUICulture, the language shown to the user is always the same!

[default.aspx.vb]

Partial Class _Default
    Inherits System.Web.UI.Page

    Shared rm As ResourceManager = HttpContext.Current.Application("RM")

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Label.Text = rm.GetString("homewelcome")
    End Sub

    Protected Overrides Sub InitializeCulture()
        SetLanguage(Request.Url.ToString)
    End Sub

    Public Shared Sub SetLanguage(ByVal URL As String)
        Dim lang As String = ""
        If URL.Contains("www.domain.nl") Then
            lang = "nl"
        ElseIf URL.Contains("www.domain.com") Then
            lang = "en"
        End If
        System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(lang)
        System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(lang)
    End Sub
End Class

[global.asax]

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    Application("RM") = New ResourceManager("strings", Assembly.Load("strings"))
End Sub

In my bin folder I have:

bin\strings.txt bin\nl\strings.nl.txt bin\en\strings.en.txt

I generate the dlls like so:

resgen strings.txt strings.resources
al /embed:strings.resources,strings.resources /out:strings.dll
resgen nl\strings.nl.resources
al /embed:nl\strings.nl.resources,strings.nl.resources /out:nl\strings.resources.dll /c:nl
resgen en\strings.en.resources
al /embed:en\strings.en.resources,strings.en.resources /out:en\strings.resources.dll /c:en

Now, all files seem to be created correctly.

However, when I go to the www.domain.com, the values from bin\strings.txt are used and NOT (like I would expect and desire), the values from bin\en\strings.en.txt

Im running on Windows 7 with IIS7.5 When I debugged I found that in my InitializeCulture method:

Protected Overrides Sub InitializeCulture()
    SetLanguage(Request.Url.ToString)
End Sub

when I check for the current System.Threading.Thread.CurrentThread.CurrentUICulture.ToString its equal to "en", so it seems that the culture is SET correctly, its only that not the correct strings.dll is used.

But there's a more strange things going on: I have this in my default.aspx <asp:Literal ID="Literal1" runat="server" Text="<%$Resources:lookingfor%>" />

  1. When I aproach www.doma开发者_运维知识库in.nl (the Dutch domain!), the Literal1 controls displays the value from "App_LocalResources\default.aspx.en.resx" and the rm.getstring shows me a value from bin\strings.txt And when I check the current System.Threading.Thread.CurrentThread.CurrentUICulture.ToString its equal to "nl"

  2. When I aproach www.domain.com (the English domain!), the Literal1 controls displays the value from "App_LocalResources\default.aspx.en.resx" and the rm.getstring shows me a value from bin\strings.txt And when I check the current System.Threading.Thread.CurrentThread.CurrentUICulture.ToString its equal to "en"

What is going on here?

So when using www.domain.nl, the WRONG strings.dll is used, but the CORRECT .resx


You can use ResourceManager's GetString(string, CultureInfo) overload to get strings in correct language.

BTW. global.asax is probably the better place to set CurrentCulture and CurrentUICulture.

EDIT Providing code sample per Peter's request

Globabal.asax

For starters, I would detect and store culture:

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires at the beginning of each request '
    Dim culture As CultureInfo
    Dim uri As Uri = Request.Url
    If uri.ToString().Contains("nederlands") Then
        culture = New CultureInfo("nl-NL")
    ElseIf uri.ToString().Contains("polski") Then
        culture = New CultureInfo("pl-PL")
    Else
        culture = New CultureInfo("en-US")
    End If

    Thread.CurrentThread.CurrentCulture = culture
    Thread.CurrentThread.CurrentUICulture = culture
End Sub

Depending on what you want to do, it might not be the best Function to overload, in your case I believe Session_Start is better (that is unless you want to give users an ability to switch language).
Another thing is, I didn't test it with domain names, I used query parameters and haven't validate them properly but it was just for the purpose of example only.

Create App_LocalResources

Instead of instantiating ResourceManager and compiling your resources manually, I can only suggest you to use App_LocalResources. You just need to right-click on your project in the Solution Explorer, choose Add -> Add Asp.Net Folder -> App_LocalResources.

Create resource files

Create appropriately named resource files: Default.aspx.resx, Default.aspx.nl.resx and add the contents you want to localize to them. In my case it was:

Default.aspx.resx (neutral aka fall-back culture resource file)
label1  Some label
label2  Some other label
Default.aspx.nl.resx (Sorry for my poor Dutch)
label1  Dit is een etiket
label2  Dit is ander etiket
Default.aspx.pl.resx
label1  Jakaś tam labelka
label2  Jakaś inna labelka

Default.aspx.vb (code behind)

In code behind you can programmatically modify contents of your web page like this:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Label2.Text = Me.GetLocalResourceObject("label2")
End Sub 

For many reasons I would not recommend this method (especially it should not be used in page load handler), however it is sometimes needed.

Default.aspx

Finally we are at our beautiful (and very useful) web page:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>

    <form id="form1" runat="server">
    <div>
      <asp:Label ID="Label1" runat="server" Text="<%$ Resources:label1 %>"></asp:Label>
      <br />
      <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>    
    </div>
    </form>
</body>
</html>

As you can see, you can access the resources with following expression: <%$ Resources:label1 %>. This will give you the string associated with label1 resource key. Important thing to note: runat="server" is not optional.

HTH. You may want to read the tutorial on Asp.Net Localization as well.


Use Culture & UICulture Page properties:

VB:

    UICulture = "en-US"
    Culture = "en-US"

    Dim cultureInfo As Globalization.CultureInfo = Globalization.CultureInfo.CreateSpecificCulture("en-US")

    Threading.Thread.CurrentThread.CurrentCulture = cultureInfo
    Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo

C#:

        UICulture = "en-US";
        Culture = "en-US";    
        Globalization.CultureInfo  cultureInfo =  Globalization.CultureInfo.CreateSpecificCulture("en-US");

        Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
        Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;


Protected Overrides Sub InitializeCulture()
Dim ui As String = String.Empty

If String.IsNullOrWhiteSpace(Request.QueryString("UI")) Then
    'ui = "en-US"
    If Not Session("UI") Is Nothing Then
        ui = Session("UI")
    Else
        ui = "en-US"
    End If
Else
    ui = Request.QueryString("UI")
End If

UICulture = ui
Culture = ui

Dim cultureInfo As Globalization.CultureInfo = Globalization.CultureInfo.CreateSpecificCulture(ui)

Threading.Thread.CurrentThread.CurrentCulture = cultureInfo
Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo

MyBase.InitializeCulture()
End Sub

I'm passing UI value through Session and QueryString, if the UI doesn't have value I set it to "en-US"

0

精彩评论

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