문제

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.

도움이 되었습니까?

해결책 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.

다른 팁

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top