Where to set/change page's culture prior to FrameworkInitialize()?

Last post 12-29-2005 12:17 PM by Fredrik N. 16 replies.

Sort Posts:

  • Smile [:)] Where to set/change page's culture prior to FrameworkInitialize()?

    05-11-2005, 4:34 AM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85
    I'm not sure if I should post this here.  What I want to do involves some new localization features provided by ASP.NET 2.0.  But my problem is quite generic even for ASP.NET 1.x.  In a shor word, where can I set/change the page's culture prior to FrameworkInitialize()?


    I am using ASP.NET 2.0 Beta 2.  I want to toggle the page between two languages by clicking a toggle button on the page.  In the button's click event handler, I will toggle the language which is saved inside a session variable.  I try to render the page using the new language, but it does not work.

    I have read three articles about the improved localization for ASP.NET 2.0, and the page lifecycle/pipeline.  They are listed at the end of this post.


    From article 1 - section "Implicit Localization Expressions", I know that the localized content of the page is decided by the following code invoked inside FrameworkInitlize().

        button1.Text = ((string)
          base.GetLocalResourceObject("LinkButtonResource1.Text"));

    Then I think I should set the page's culture before the execution of FrameworkInitlize().  But I'm not sure of the exact place in the page lifecycle.


    In article 2 - section "Page Lifecycle", there are a list of Page Lifecycle methods.  The following is a partial list at the beginning of the lifecycle that I think are relevant with my problem.

        Constructor
        Construct
        TestDeviceFilter
        AddParsedSubObject
        DeterminePostBackMode
        OnPreInit
        LoadPersonalizationData
        InitializeThemes
        OnInit


    In article 3 - section "The Page Lifecycle", it says:

    Once the HTTP page handler class is fully identified, the ASP.NET run time calls the handler's ProcessRequest method to process the request. ... (it) begins by calling the method FrameworkInitialize, which builds the controls tree for the page. The method is a protected and virtual member of the TemplateControl class - the class from which Page itself derives. Any dynamically generated handler for an .aspx resource overrides FrameworkInitialize. In this method, the whole control tree for the page is built.

    Next, ProcessRequest makes the page transit various phases: initialization, loading of view state information and postback data, loading of the page's user code and execution of postback server-side events. After that, the page enters in rendering mode: the updated view state is collected; the HTML code is generated and then sent to the output console. Finally, the page is unloaded and the request is considered completely served.


    From this, I deduce that the method FrameworkInitlize() is called at least prior to OnPreInit().  But I do not know where its exact position is in the lifecycle.

    Anyway, I tried the following.

    I override the method Construct to toggle the current thread's culture, as shown below.  But it does not work.  The displayed page is still in the browser's language.

        protected override void Construct()
        {
            base.Construct();

            string l;
            if(Thread.CurrentThread.CurrentUICulture.Name == "en-US")
            {
                l = "zh-CN";
            }
            else
            {
                l = "en-US";
            }
            CultureInfo ci = CultureInfo.CreateSpecificCulture(l);
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci;
        }

    I also tried to overried OnInit() and OnPreInit() to set the page's culture, but it is still futile.

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            Page.Culture = Language;
        }

    I'll be greatly appreciated if anyone can provide any explanation/suggestions/workarounds to my problem?  Thanks a lot in advance!


    Reference:
    Articles 1. ASP.NET 2.0 Localization Features: A Fresh Approach to Localizing Web Applications
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/ASP2local.asp

    Articles 2. ASP.NET 2.0 Internals
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/internals.asp

    Articles 3. The ASP.NET Page Object Model
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnet-pageobjectmodel.asp


    Zhu Ming


    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-11-2005, 5:52 AM
    • All-Star
      29,644 point All-Star
    • Fredrik N
    • Member since 06-22-2002, 1:03 AM
    • Sweden
    • Posts 5,334
    • TrustedFriends-MVPs
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-11-2005, 12:09 PM
    • Contributor
      6,285 point Contributor
    • BrockAllen
    • Member since 05-05-2003, 2:46 PM
    • Providence, RI
    • Posts 1,253

    Fredrik's approach works, but it's a PITA (IMO) if it's to be done on every page (or in a common base class). We just discussed this the other day, so it's an alternative for you:

    http://forums.asp.net/920819/ShowPost.aspx

    -Brock

     

    DevelopMentor
    http://staff.develop.com/ballen
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-11-2005, 11:43 PM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85
    Thanks, Fredrik and Brock!

    I've tried and both methods work!  As I need to toggle the culture for the whole web site instead of individual page, I prefer to do it in application's
    PreRequestHandlerExeute event handler.

    Please refer to the help of
    HttpApplication Class.
    An application executes events that are handled by modules or user code that is defined in the Global.asax file in the following sequence:
       1. BeginRequest
       2. AuthenticateRequest
       3. PostAuthenticateRequest
       4. AuthorizeRequest
       5. PostAuthorizeRequest
       6. ResolveRequestCache
          An event handler (a page corresponding to the request URL) is created at this point.
       7. PostResolveRequestCache
       8. PostMapRequestHandler
       9. AcquireRequestState
      10. PostAcquireRequestState
      11. PreRequestHandlerExecute
          The event handler is executed.
      12. PostRequestHandlerExecute
      13. ...

    I tried BeginRequest, but it does not work.  I guess the reason is that the Page.Request will be created later and will overwrite the thread culture set in BeginRequest.
    Till 10. PostAcquireRequestState, the request is prepared, and only after that can we change the thread culture.  Doing that in 11. PreRequestHandlerExecute is exactly Brock's approach.
    "The event handler is executed." between 11 and 12 is the whole page's processing including any event handlers in the webform's codebehind, I think. Fredrik's approach, setting the thread culture in InitializeCulture is exactly here.

    I still have one more problem.  The toggle button's event handler will be executed after the thread culture is set (either in PreRequestHandlerExecute or in InitializeCulture).  The result is that after the page reaches the browser the target culture will be different from the thread culture.  While in any other events, since the target culture is not changed, the target culture will be the same as the thread culture.  This is a inconsistent behavour.  But it is not much a ASP.NET technical problem.

    Thanks!
    Zhu Ming
    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-12-2005, 12:28 AM
    • Contributor
      6,285 point Contributor
    • BrockAllen
    • Member since 05-05-2003, 2:46 PM
    • Providence, RI
    • Posts 1,253

    Yep and for that last problem I always take the hack approach of Response.Redirect(Request.Path) to make the browser come back in so they see the changes immediaetly.

    -Brock

     

    DevelopMentor
    http://staff.develop.com/ballen
  • Smile [:)] Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-12-2005, 4:30 AM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85
    It works!  The only drawback is that the input such as content in a TextBox will be gone after the redisplay of the same page.  The user has to enter it again.

    Thanks, Brock!
    Zhu Ming

    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-13-2005, 6:01 AM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85
    I have another question.  Is there a way to localize web.sitemap?

    Thanks!
    Zhu Ming
    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-13-2005, 6:06 AM
    • All-Star
      29,644 point All-Star
    • Fredrik N
    • Member since 06-22-2002, 1:03 AM
    • Sweden
    • Posts 5,334
    • TrustedFriends-MVPs
    /Fredrik Normén - fredrikn @ twitter

    ASPInsider

    Microsoft MVP, MCSD, MCAD, MCT

    ASPInsiders
    My Blog
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-14-2005, 6:55 AM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85

    Thanks, Fredrik!


    I like the implicit expression because it will save more typing.

    <siteMap enableLocalization="true" xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
        <siteMapNode url="~/Default.aspx" title="Home"  description="" resourceKey="Home">


    In addition, the web.sitemap.resx and its localized resources need to be put in App_GlobalResources folder.  (I'm using Beta 2.)


    Zhu Ming

    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-27-2005, 10:46 AM
    • Member
      188 point Member
    • bizbiz
    • Member since 05-27-2005, 2:38 PM
    • Posts 47
    Can you give me an example of your global.asax file ?

    I have a page with 4 resources like this :
    Register.aspx.resx
    Register.aspx.en-CAresx
    Register.aspx.fr-CAresx
    Register.aspx.fr-FR.resx

    When I put a break point in the Page_load event, the resource manager is load with the Register.aspx.resx.  But my currentCulture is en-CA and the uiCulture is en.  Anyone can help me ?

    Do you write the keyword new ?  Because it give me a warning if I don't do that.

    new void PreRequestHandlerExecute(Object sender, EventArgs e)

    {

       // create culture preference cookies if they don't exist yet
       // otherwise set current thread to value of those cookies
       System.Web.HttpCookie cookie = Request.Cookies["QuickStartLocalize"];

       if (cookie != null)
       {
          try
          {
             
    string currentUICulture = cookie.Values["UICulture"];
             
    string currentCulture = cookie.Values["Culture"];

             
    if ( currentUICulture != null && currentUICulture.Length > 0)
            {
                System.Threading.
    Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(currentUICulture);
             }

             if ( currentCulture != null && currentCulture.Length > 0)
             {
                System.Threading.
    Thread.CurrentThread.CurrentCulture =new System.Globalization.CultureInfo(currentCulture);
             }
          }
          catch (System.Exception)
          {
          }
       }
    }

  • Smile [:)] Re: Where to set/change page's culture prior to FrameworkInitialize()?

    05-27-2005, 11:36 PM
    • Member
      192 point Member
    • blackpuppy
    • Member since 04-29-2005, 5:42 AM
    • Posts 85
    First, your resx files need to be named like this (notice the dot before resx):
    Register.aspx.en-CA.resx
    Register.aspx.fr-CA.resx
    I guess they are just typos.

    My Global.asax is shown below.

    <%@ Application Language="C#" %>
    <%@ Import Namespace="System.Globalization" %>
    <%@ Import Namespace="System.Threading" %>

    <script RunAt="server">
        // other methods are ommitted for brevity.

        protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
        {
            try
            {
                string lang = (string)Session["Language"];
                //Page.Culture = lang;  // This does not work!  Must assign Thread.CurrentThread.CurrentUICulture!
                Thread.CurrentThread.CurrentUICulture =
                    new CultureInfo(lang);
            }
            catch
            {
            }
        }
    </script>

    You do not need to write the prototype yourself.  You can let Visual Studio do that for you.  There are two dropdown list above the code pane.  In the left dropdown list, select "Application".  And then in the right dropdown list, select the event handler you want such as "PreRequestHandlerExecute".  The event handler stub will be created for you.  Then you can write your code inside.

    Hope this is of some use to you.

    Thanks and best regards!
    blackpuppy
    ----------------------------------------------------
    The more you know, the more you know you don't know.
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    09-30-2005, 4:31 AM
    • Member
      15 point Member
    • wpclueless
    • Member since 09-30-2005, 7:36 AM
    • Posts 3
    I have tried this and it works for a listbox selection and a button, but when I try it using an image button it fails in the application_prerequesthandlerexecute saying that session state in not available in this context - any ideas why?
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    12-28-2005, 5:24 PM
    • Member
      55 point Member
    • martin.
    • Member since 12-19-2005, 8:00 AM
    • Posts 12

    I can't get it to work when I want to set the prefered languange in global.asax. I've tried both memberships and session. Membership always i nothing, and when I try to use sessions i get the error "Session state is not available in this context"

    What am i doing wrong here?

    This is in my global.asax in Application_PreRequestHandlerExecute

    If Session("culture") IsNot Nothing Then
    Try
    Dim ci As New Globalization.CultureInfo(Session("culture").ToString)
    System.Threading.Thread.CurrentThread.CurrentUICulture = ci
    System.Threading.Thread.CurrentThread.CurrentCulture = ci
    Catch ex As Exception
    System.Threading.Thread.CurrentThread.CurrentUICulture =
    New System.Globalization.CultureInfo("sv-se")
    End Try

    End If

     

     

  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    12-29-2005, 4:15 AM
    • All-Star
      29,644 point All-Star
    • Fredrik N
    • Member since 06-22-2002, 1:03 AM
    • Sweden
    • Posts 5,334
    • TrustedFriends-MVPs

    At the PreRequestHandlerExecute the Session variables is not yet available for use. What you can do is to store the culture into a cookie or maybe if you already use the Profile feature, you can use it to store the language a user has selected. You can also instead of the PreRequestHandlerExecute try to use the Application_AcquireRequestState.

     

    Take a look at the following posts:

     

    http://fredrik.nsquared2.com/viewpost.aspx?PostID=153

     

    http://fredrik.nsquared2.com/viewpost.aspx?PostID=309

    /Fredrik Normén - fredrikn @ twitter

    ASPInsider

    Microsoft MVP, MCSD, MCAD, MCT

    ASPInsiders
    My Blog
  • Re: Where to set/change page's culture prior to FrameworkInitialize()?

    12-29-2005, 9:12 AM
    • Member
      55 point Member
    • martin.
    • Member since 12-19-2005, 8:00 AM
    • Posts 12
    Works great with the profile feature. Thank you very much!
Page 1 of 2 (17 items) 1 2 Next >