Question

I've setup a web site to be localized using Global resources only. I'm having a hard time figuring out why a page is always giving inconsistent behavior every time I trigger a culture change through a drop down list. Here are my resource files:

Resources: Resource files

Setup Here is the Base Page that is inherited by all pages:

  public partial class BaseWebForm : Page
  {

    protected override void InitializeCulture()
    {
      if (Session["UserLanguage"] != null)
      {
        String selectedLanguage = Session["UserLanguage"].ToString();
        UICulture = selectedLanguage;
        Culture = selectedLanguage;

        CultureInfo culture = CultureInfo.CreateSpecificCulture(selectedLanguage);
        Thread.CurrentThread.CurrentCulture = culture;
        Thread.CurrentThread.CurrentUICulture = culture;
      }

      base.InitializeCulture();
    }

  }

I'm using a Session variable, UserLanguage, to manage selected language. My site assumes en-US as default language and the drop down is displayed on the login page. That means the user cannot change language on any page as, upon login page, a service retrieves available languages.

I'm using Master page and I've handled the menus, breadcrumb SiteMapPath, and LTR-RTL there.

On the actual page, here is a brief:

  public partial class PublicLogOn : BaseWebForm
  {

    protected void Page_Load(object sender, EventArgs e)
    {
      try
      {
        if (Request.IsAuthenticated)
        {
          SiteLogger.NLogger.Info("Request Authenticated");
          SiteLogin.RedirectToDefaultPage();
        }

        #region Handle Return URL

        if (HttpContext.Current.Request.QueryString["ReturnUrl"] != null && !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ReturnUrl"]))
        {
          var tempUrl = HttpContext.Current.Request.QueryString["ReturnUrl"];

          SiteLogger.NLogger.Info("Return URL : " + tempUrl);

          if (tempUrl.Contains(@"/SecuredArea/AdminArea/"))
          {
            buttonLogOn.Visible = false;
            // buttonAdminLogOn.Visible = true;
          }
          else if (tempUrl.Contains(@"/SecuredArea/EmployeeArea/"))
          {
            buttonLogOn.Visible = true;
            // buttonAdminLogOn.Visible = false;
          }
          else
          {
            // buttonLogOn.Visible = buttonAdminLogOn.Visible = true;
            buttonLogOn.Visible = true;
          }
        }

        #endregion


        if (!Page.IsPostBack)
        {
          SiteLogger.NLogger.Info("Loading Languages and Directories");

          // Actual language loading                
          if (!LoadLanguages() || !LoadDirectories())
          {
            SiteLogger.NLogger.Info("Loading Languages or Directories failed!");
            return;
          }

          SiteLogger.NLogger.Info("Completed : PublicLogOn.PageLoad");
        }

        // Don't know why this fails and the drop-down still shows en-US even culture is ur-PK    
        //if (Session["UserLanguage"] != null)
        //{
        //  DDLLanguages.SelectedValue = Session["UserLanguage"].ToString();
        //}

      }
      catch (Exception ex)
      {
        SiteLogger.NLogger.Error("Error in PublicLogOn.Page_Load", ex.Message);
      }

    }

    private Boolean LoadLanguages()
    {
      Boolean methodResult;
      try
      {
        SiteLogger.NLogger.Info("In Load Languages");

        // This line also mess up
        // Session["UserLanguage"] = null;

        DDLLanguages.Items.Clear();
        var fetchedLanguages = UserManagePage.GetOrganizationLanguages();

        foreach (var oneFetchedLanguage in fetchedLanguages)
        {
          DDLLanguages.Items.Add(new ListItem(oneFetchedLanguage.LanguageSymbol, oneFetchedLanguage.LanguageSymbol));
        }

        if (fetchedLanguages.Count() == 1)
        {
          DDLLanguages.Enabled = false;
        }

        methodResult = true;
      }
      catch (Exception exp)
      {
        SiteLogger.NLogger.Error("Error in load languages : ", exp.ToString());        
        labelMessage.Text = MessageFormatter.GetFormattedErrorMessage("Error retrieving organization languages.");
        methodResult = false;
      }

      return methodResult;
    }

    private Boolean LoadDirectories()
    {
      // Nothing to-do with code-in-question
    }

    protected void ButtonLogOn_Click(object sender, EventArgs e)
    {
      // Nothing to-do with code-in-question
    }

    protected void DDLLanguages_SelectedIndexChanged(object sender, EventArgs e)
    {
      Session["UserLanguage"] = DDLLanguages.SelectedValue;

      // Reload-hack. Was recommended on SO.
      Response.Redirect(Request.Url.AbsolutePath);
    }

  }

After all of this, there one more point where the session variable is used as read-only: I'm using a header to tell my server that the client's using xyz language and that server should return translated data, where applicable:

public class CustomInspectorBehavior : IClientMessageInspector, IEndpointBehavior
{
  #region IClientMessageInspector
  public object BeforeSendRequest(ref Message request, IClientChannel channel)
  {
    string languageIdentifier;
    if (HttpContext.Current.Session["UserLanguage"] != null)
    {
      languageIdentifier = HttpContext.Current.Session["UserLanguage"].ToString();
    }
    else
    {        
      languageIdentifier = CultureInfo.CurrentCulture.ToString();
    }
    var typedHeader = new MessageHeader<string>(languageIdentifier);
    var untypedHeader = typedHeader.GetUntypedHeader("LanguageIdentifier", "");
    request.Headers.Add(untypedHeader);

    return null;

  }

  #endregion

  #region IEndpointBehavior

  public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
    var inspector = new CustomInspectorBehavior();
    clientRuntime.MessageInspectors.Add(inspector);
  }

  #endregion
}

Results Expected: I change the selected value on the drop-down and the page reload with new language + secure the selection in session. Now upon going to other pages, the new language is presented.

Actual: "LOL". I change the selected value from the default en-US to ur-PK and the web site updates to Urdu. All pages are in Urdu. I try to select en-US again and I realize I'm stuck with Urdu. The base page's InitializeCulture() trigger way too early and it finds Session["UserLanguage"] = ur-PK'. After that thePage_Loadof thePublicLogOnpage triggers effectively putting Drop down's selected value to still ur-PK. After thatDDLLanguages_SelectedIndexChangedof thePublicLogOn` page triggers updating the session variable to the selected value which is set to ur-PK from the recent PageLoad. Issue. The Hack triggers in the end repeating the cycle one more time.

I'm trying a number of things but end in this mini-loop. Any help will be appriciated.

Was it helpful?

Solution 2

I re-did the whole thing from scratch. Turns out there was one or two variables being static at IIS level which were the cause of all the pain.

OTHER TIPS

You could do a redirect after your set the new language in the session.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top