Wednesday 20 May 2009

Password FieldTemplates for Dynamic Data (UPDATED)

See this thread on the Dynamic Data Forum where I suggested you could use [DataType(DataType.Password)] attribute to mark the field as a password field and alternative would be to create a custom FieldTemplate and use [UIHint("Password")] to set it.

This just means the extra logic I implement for the password is only used on password fields and not all Text fields.

<%@ Control 
    Language="C#" 
    CodeBehind="Password.ascx.cs" 
    Inherits="DD_EF4_PasswordField.PasswordField" %>

<asp:Literal runat="server" ID="Literal1" />

Listing 1 – Password.ascx

using System;
using System.Web.UI;

namespace DD_EF4_PasswordField
{
    public partial class PasswordField : System.Web.DynamicData.FieldTemplateUserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // add a string of '*' the max length of the field
            var length = Column.MaxLength > 20 ? 20 : Column.MaxLength;
            Literal1.Text = new String('*', length);
        }

        public override Control DataControl
        {
            get
            {
                return Literal1;
            }
        }
    }
}

Listing 2 – Password.ascx.cs

Listing 1 & 2 represent the Password (Normal) FieldTemplate.

This is FieldTemplate just displays a list of '*' the max length of the field instead of the actual text.

<%@ Control 
    Language="C#" 
    CodeBehind="Password_Edit.ascx.cs" 
    Inherits="DD_EF4_PasswordField.Password_EditField" %>

<asp:TextBox 
    ID="TextBox1" 
    runat="server" 
    TextMode="Password"
    CssClass="DDTextBox" >
</asp:TextBox>

<asp:RequiredFieldValidator 
    runat="server" 
    ID="RequiredFieldValidator1"
    CssClass="DDControl" 
    ControlToValidate="TextBox1" 
    Display="Dynamic" 
    Enabled="false" />
<asp:RegularExpressionValidator 
    runat="server" 
    ID="RegularExpressionValidator1" 
    CssClass="DDControl" 
    ControlToValidate="TextBox1" 
    Display="Dynamic" 
    Enabled="false" />
<asp:DynamicValidator 
    runat="server" 
    ID="DynamicValidator1" 
    CssClass="DDControl" 
    ControlToValidate="TextBox1" 
    Display="Dynamic" />

Listing 3 – Password_Edit.ascx

using System;
using System.Collections.Specialized;
using System.Web.DynamicData;
using System.Web.UI;

namespace DD_EF4_PasswordField
{
    public partial class Password_EditField : FieldTemplateUserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Column.MaxLength < 20)
            {
                TextBox1.Columns = Column.MaxLength;
            }
            TextBox1.ToolTip = Column.Description;

            SetUpValidator(RequiredFieldValidator1);
            SetUpValidator(RegularExpressionValidator1);
            SetUpValidator(DynamicValidator1);
        }

        protected override void OnDataBinding(EventArgs e)
        {
            base.OnDataBinding(e);
            TextBox1.MaxLength = Math.Max(FieldValueEditString.Length, Column.MaxLength);
        }

        protected override void ExtractValues(IOrderedDictionary dictionary)
        {
            if (TextBox1.Text.Length > 0)
                dictionary[Column.Name] = ConvertEditedValue(TextBox1.Text);
        }

        public override Control DataControl
        {
            get
            {
                return TextBox1;
            }
        }
    }
}

Listing 4 – Password_Edit.ascx.cs

Listings 3 & 4 are for the Edit version Password_Edit FieldTemplate.

Updated: Listing 4 has been updated with the line if (TextBox1.Text.Length > 0) so that in edit mode if you do not enter a value it will not return an empty string.

Here the TextBox’s TextMode is set to Password so that any password you type in is hidden.

Note: The TextBox does not show any text in the TextBox.Text property when in Password mode this is normal behaviour.

9 comments:

Anonymous said...

very cool, it´s already incorporated in my framework
tks a lot

Alok Kumar said...

this is nice way but we can probably also write simple line to set the attribute like
txtPassword.Attributes.Add("value", "password");

This will have same effect.

Alok Kumar
eXtendCode

Stephen J. Naughton said...

Hi Alok Kumar, I will be doing a password with confirmation etc for Dynamic Data shortly that will be a log better.

Steve :D

Alok Kumar said...

Ok Steve that will great. Look forward to that

Stephen J. Naughton said...

The newer sample is here

Steve

Anonymous said...

Gonna try field template with field validator on date time solution I am working on for effective to and effective from records control. Thanks Steve!

Stephen J. Naughton said...

I've already created a DataTime Validator but am just missing the client side JavaScript to make it worth posting :)

Steve

Zach said...

I had to store my passwords with a salted hash and have the user re-enter their password.

This was my solution:
http://www.squenchy.com/dynamic-data-password-field-template-with-salted-hashing-and-password-confirmation.aspx

Unknown said...

Hi steve,

I was trying to use your code for the password template in my dynamic data project.

My scenario: I want the users to be able to update their password field along with other fields(user data like question,comments etc). Initially for user in edit mode, the password field should be displayed as blank and If they enter new password, it should be updated in the database. But if they don't update the password field and update some other fields it should just update other fields.

I have used the above code, it works fine when the user updates the password field but when the user doesn't edit password field and update other fields, it gives a validation message 'password field is required'(this should not happen for my case).

So I have removed requiredfieldvalidator and added a condition like below:
if (TextBox1.Text.Length > 0)
{
SetUpValidator(RegularExpressionValidator1);
SetUpValidator(DynamicValidator1);
}
which works. Do you have any other idea for the above scenario?

Thanks,
sreethi