在站点级本地化期间,asp.net webform中的行为不一致

时间:2013-12-08 15:59:48

标签: c# asp.net globalization

我已经设置了一个仅使用全局资源进行本地化的网站。每次通过下拉列表触发文化更改时,我都很难弄清楚为什么页面始终会产生不一致的行为。这是我的资源文件:

资源: Resource files

设置 这是所有页面都继承的基页:

  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();
    }

  }

我正在使用会话变量UserLanguage来管理所选语言。我的网站将en-US视为默认语言,并在登录页面上显示下拉列表。这意味着用户无法更改任何页面上的语言,因为在登录页面上,服务会检索可用的语言。

我正在使用母版页,我已经处理了菜单,面包屑SiteMapPath和LTR-RTL。

在实际页面上,这里有一个简要说明:

  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);
    }

  }

在所有这一切之后,会话变量被用作只读的另一点:我使用标头告诉我的服务器客户端使用xyz语言并且该服务器应返回已翻译的数据,如果适用:

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
}

结果 预期:我在下拉列表中更改选定的值,并使用新语言重新加载页面+保护会话中的选择。现在,在转到其他页面时,会出现新语言。

实际:“LOL”。我将所选值从默认的en-US更改为ur-PK,并将网站更新为Urdu。所有页面都在乌尔都语。我试着再次选择en-US,我意识到我被乌尔都语困住了。基页的InitializeCulture()触发方式太早,发现Session["UserLanguage"] = ur-PK'. After that the Page_Load of the PublicLogOn page triggers effectively putting Drop down's selected value to still ur-PK. After that DDLLanguages_SelectedIndexChanged of the PublicLogOn页面触发将会话变量更新为所选值从最近的PageLoad设置为ur-PK。问题。 Hack最终会再次触发循环。

我正在尝试很多东西但是在这个迷你循环中结束。任何帮助都会得到满足。

2 个答案:

答案 0 :(得分:1)

您可以在会话中设置新语言后进行重定向。

答案 1 :(得分:0)

我从头开始做了整件事。事实证明,在IIS级别有一个或两个变量是静态的,这是所有痛苦的原因。