Monday, November 26, 2007

I have a website that I created that uses an ASP.NET Login control to assist in user authentication on the site.  I've used the Login control on other sites and it's provides a very convenient mechanism for authenticating a user.  On this site particular site I have the Login control contained within a wrapper control (which I called LoginBox).  Due to the nature of this site, the LoginBox does not exist on the page in the ASP.NET HTML markup but rather is added to the page dynamically.  As such I don't have the convenience of editing the HTML markup of the asp:Login control directly but must interact with it programmatically.

The Login control provides several properties through which I can achieve a nice look and feel.  It contains child controls for the title, labels, textboxes, required field validators, checkboxes, and buttons.  Each of these can be customized via CSS styles or by directly assigning values to the controls' properties.

In this particular site I needed to extend the appearance of the control, adding some textboxes to the control.  At first this wasn't very intuitive, but I'll show you that it is, in fact, quite easy to achieve.  You can easily add fields to the control (e.g., a 'verify password' field, an 'email' field, a CAPTCHA control, etc) by customizing the LayoutTemplate of the Login control.

Were I to have had the control in the HTML markup of my page this would be a piece of cake.  Note, via the designer, you can simply click the Login control's smart tag and click “Convert to Template“ or create it manually:

<asp:Login runat="server" id="login">
  <LayoutTemplate>
    <!-- HTML template here -->
  </LayoutTemplate>
</asp:Login>

However, as the control is being generated entirely in code, the template must be created programmatically.  As a bare minimum, you need two controls in your template that implement the ITextControl interface for the control to render; otherwise, you'll get an exception (TextBoxes will suffice or any control you create that implements that interface).  These controls are UserName and Password.  I recommend adding the login button as well (Button, LinkButton, or ImageButton) with a CommandName set to “Login“.  Using a template, you can fully customize the look and feel of the output.  Note, that when you go the route of creating a custom template, you are solely responsible for the output.  In other words, you're completely replacing the output that the Login control generates; if you want field validators, you need to add them.

// somewhere in the page (e.g., Page.Init)
Login login = new Login();
login.LayoutTemplate = new LoginTemplate();
Controls.Add(login);

internal class LoginTemplate : ITemplate {
  public void InstantiateIn(Control container) {
    TextBox txtUserName = new TextBox();
    txtUserName.ID = "UserName";
    container.Controls.Add(txtUserName);

    TextBox txtPassword = new TextBox();
    txtPassword.ID = "Password";
    container.Controls.Add(txtPassword);

    ImageButton btnLogin = new ImageButton();
    btnLogin.ID = "LoginButton";
    btnLogin.ImageUrl = "~/images/LoginButton.gif";
    btnLogin.CommandName = "Login";
    container.Controls.Add(btnLogin);
  }
}

With this, I have an extremely boring-looking Login control, but you get the idea.

When the page is posted back, you can easily retrieve the contents of any control you added to the template by calling the .FindControl() method, referencing it by name:

string emailAddress = ( ( TextBox )login.FindControl("txtEmail") ).Text;

Monday, November 26, 2007 3:36:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Saturday, November 03, 2007

I had the opportunity to present at the Utah Code Camp today on the topic of Regular Expressions.  This topic is near and dear to my heart, but (being my worst critic) I feel that I couldn't get my act together.  In part I feel that the presentation went very poorly; it was definitely among my worst.  I felt my explanations lacking, incomplete, or erroneous, my examples unsuccessful or poor, and my 'togetherness' absent.  It was a very far cry from a similar presentation I had given back in Sept 2006 to the Utah .NET User Group which was among my best I feel.  That made it all the more disappointing for me.

I guess on the positive side I've updated my RegexTester application and it's available for download here.  Thanks to all that came and participated.  We had a great turnout to the event so that was very positive.  I just wish my presentation hadn't ruined my day...it's been lousy ever since.  I guess you can't win them all.

Saturday, November 03, 2007 1:54:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [3]  |  Trackback