Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
806 views
in Technique[技术] by (71.8m points)

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

Im struggling with gettings the values from the correct strings.txt in my resource files in my in 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:

binstrings.txt bin lstrings.nl.txt binenstrings.en.txt

I generate the dlls like so:

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

Now, all files seem to be created correctly.

However, when I go to the www.domain.com, the values from binstrings.txt are used and NOT (like I would expect and desire), the values from binenstrings.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.domain.nl (the Dutch domain!), the Literal1 controls displays the value from "App_LocalResourcesdefault.aspx.en.resx" and the rm.getstring shows me a value from binstrings.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_LocalResourcesdefault.aspx.en.resx" and the rm.getstring shows me a value from binstrings.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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...