• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1312
  • Last Modified:

ASP.NET & Localization: Can't Always Access Global resx from Code Behind

This is likely a real "newbie" question, but I am new to ASP.NET and want to check with the experts before proceeding.  

This invoives a web application using ASP.NET 4.0 with VB, using ASP membership. I am setting up localization using global resource files, and am in the process of localizing my few starter pages before building the bulk of the application.

Question: Is it expected that some strings can't be set for localization using the strongly-typed approach in the code behind, or am I just missing some VB syntax that would allow me to set all strings in the code behind?

Specifics: I am currently localizing the built-in Login.aspx page provided through ASP Membership. I have localized the first three strings using the Page_Load event in the code behind file, like so:

        lblHeader.Text = Resources.iFAaccount.Log_In.ToString
        lblInstrux.Text = "<b>" & Resources.iFAaccount.Please_enter_username.ToString & "</b>"
        hypReg.Text = Resources.iFAaccount.Click_here_to_register.ToString

However, when I reached the login control itself, I couldn't figure out how to access the required text properties, so I've added this localization within the ASP markup (see lines 23, 25, 28, 32, 35, 40 and 45 ):

<%@ Page Title="" culture="auto" Language="VB" MasterPageFile="~/SiteIFA.master" AutoEventWireup="false" CodeFile="Login.aspx.vb" Inherits="Account_LoginIFA" %>

<asp:Content ID="Content4" ContentPlaceHolderID="contentpanel" Runat="Server">
    <h2>
        <asp:Label ID="lblHeader" runat="server" ></asp:Label>
    </h2>
    <p>
        <asp:Label ID="lblInstrux" runat="server" ></asp:Label>
    </p>
    <p>
        <asp:HyperLink  ID="hypReg" runat="server" NavigateUrl="~/Account/Register.aspx" EnableViewState="false"></asp:HyperLink>
     </p>
    <asp:Login ID="LoginUser" runat="server" EnableViewState="false" OnLoggedIn="SetProfileValues" RenderOuterTable="false">
        <LayoutTemplate>
            <span class="failureNotification">
                <asp:Literal ID="FailureText" runat="server"></asp:Literal>
            </span>
            <asp:ValidationSummary ID="LoginUserValidationSummary" runat="server" CssClass="failureNotification" 
                 ValidationGroup="LoginUserValidationGroup"/>
            <div class="accountInfo">
            <asp:Panel ID="panelAcctInfo" runat="server">
                <fieldset class="login">
                    <legend id="lgndAcct" runat="server" innertext="<%$ Resources:iFAaccount, Account_Information %>"></legend>
                    <p>
                        <asp:Label ID="lblUser" runat="server" AssociatedControlID="UserName" Text="<%$ Resources:iFAaccount, User_Name %>"></asp:Label>
                        <asp:TextBox ID="UserName" runat="server" CssClass="textEntry"></asp:TextBox>
                        <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName" 
                             CssClass="failureNotification" ErrorMessage="<%$ Resources:iFAaccount, User_name_is_required %>" ToolTip="User Name is required." 
                             ValidationGroup="LoginUserValidationGroup">*</asp:RequiredFieldValidator>
                    </p>
                    <p>
                        <asp:Label ID="lblPwd" runat="server" AssociatedControlID="Password" Text="<%$ Resources:iFAaccount, Password %>"></asp:Label>
                        <asp:TextBox ID="Password" runat="server" CssClass="passwordEntry" TextMode="Password"></asp:TextBox>
                        <asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password" 
                             CssClass="failureNotification" ErrorMessage="<%$ Resources:iFAaccount, Password_is_required %>" ToolTip="Password is required." 
                             ValidationGroup="LoginUserValidationGroup">*</asp:RequiredFieldValidator>
                    </p>
                    <p>
                        <asp:CheckBox ID="RememberMe" runat="server"/>
                        <asp:Label ID="RememberMeLabel" runat="server" AssociatedControlID="RememberMe" CssClass="inline" Text="<%$ Resources:iFAaccount, Keep_me_logged_in %>"></asp:Label>
                    </p>
                </fieldset>
                </asp:Panel>
                <p class="submitButton">
                    <asp:Button ID="btnLogin" runat="server" CommandName="Login" Text="<%$ Resources:iFAaccount, Log_in %>" ValidationGroup="LoginUserValidationGroup"/>
                </p>
            </div>
        </LayoutTemplate>
    </asp:Login>
</asp:Content>

Open in new window


This is all working fine, and I'll continue on if this is the best (only?) approach, but I wanted to check first if there's a way to manage all of this using the strongly-typed approach in the code behind file.

Thanks in advance for your input!
0
JMS1965
Asked:
JMS1965
  • 5
  • 2
1 Solution
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Hello buddy, I prefer using resx files for my localization projects, they are very flexibles to use and easy to mantain in an ASPNET application, to make use of this I do the next:
I create a App_LocalResources folder at the same level of the aspx files that are going to use the resources.
By example:
If a have a SignIn.aspx, then inside of App_LocalResources is there a SignIn.aspx.resx resource file, this is going to be my default fallback resource file for that page, then a can add a SignIn.aspx.es.resx for support spanish, and so on.

To access the values inside those resources files I use this methods:
Example from the codebehind:
Label1.Text = GetLocalResourceObject("EmailAddressRequired").ToString();

Open in new window


Example from the aspx (to bind to control properties)::
<asp:Literal runat="server" Text="<%$ Resources:WhatIsYourEmailAddress %>"></asp:Literal>

Open in new window


You can also create a App_GlobalResources folder at your application root, as it name indicate it is global to the application, so the values of the resources files inside are available to all the application, inside it you must put .resx files too, it follow the same logic explained for local resources.

To access it values you can do this:

Example from the codebehind:
For global resources VS create a strong type class.
Label1.Text = Resources.MyGlobalText.Continue;

Open in new window


Example from the aspx (to bind to control properties):
Resouce file "MyGlobalText", Key "Continue"
<asp:Literal runat="server" Text="<%$ Resources:MyGlobalText, Continue %>"></asp:Literal>

Open in new window


Well I hope this info is useful to you, this method are worked very well for me, sorry if my english is not very well.
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Oh I forget to say, to access the global resources from your code behind you can also use this method (example):
Label1.Text = GetGlobalResourceObject("MyGlobalText", "Continue").ToString();

Open in new window

0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
If you dont have to much background info about resx files structure here you have a useful link:
http://msdn.microsoft.com/en-us/library/ekyft91f(v=VS.90).aspx

By the way, you can also create a resx file for a specify culture, based in my last example:
SignIn.aspx.en.resx <- default for English
SignIn.aspx.en-us.resx <- For English in usa
SignIn.aspx.en-au.resx <- For English in Australia
SignIn.aspx.es.resx <- Default for spanish
SignIn.aspx.es-ve.resx <-For spanish venezuela
SignIn.aspx.es-mx.resx <- For spanish Mexico

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
JMS1965Author Commented:
Hello -

Thanks for the information, but I don't think you understood my question (my fault).  I am using all the methods you presented for localizing. I prefer the global files and the strongly-typed approach:

myLabel.Text = Resources.fileName.keyname

My question is why, in this login page, can I use that approach on some labels but not others? I suspect it has something to do with them being within a login control or field set.  For example, here is line 32 from the ASP code I provided above:

<asp:Label ID="lblPwd" runat="server" AssociatedControlID="Password" Text="<%$ Resources:iFAaccount, Password %>"></asp:Label>

I would like to replace the "Text=..." shown here with this line in the code behind file:

lblPwd.Text = Resources.iFAaccount.Password

But, the code behind does not recognize "lblPwd", or any of the controls within the ASP.Login control.  Is that just the way it is, or is there a way to refer to "lblPwd" in code?

Thanks!
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Oh sorry buddy, yes of course:
VBNET
Dim lblPwd As Label = LoginUser.FindControl("lblPwd")
lblPwd.Text = Resources.iFAaccount.Password

Open in new window


C#
Label lblPwd = (Label)LoginUser.FindControl("lblPwd");
lblPwd.Text = Resources.iFAaccount.Password;

Open in new window


Sorry, I misunderstand your question...
0
 
Carlos VillegasFull Stack .NET DeveloperCommented:
Or just one line:
VBNET
CType(LoginUser.FindControl("lblPwd"), Label).Text = Resources.iFAaccount.Password

Open in new window


Be careful if for some reason FindControl return Nothing, because it can't find the control where you are trying to find it.

I hope this help.
0
 
JMS1965Author Commented:
Thanks - that's what I was looking for!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now