Search code examples
asp.netvalidationformviewunique-constraintcustomvalidator

Ensure field is unique in a formview


In my asp page I have a FormView which is used to display and edit the info for a person. Each person has a name which has to be unique which I'm validating using a CustomValidator:

<asp:FormView runat = "server"                                     
              ID = "PersonFormView"
              DefaultMode = "Edit"
              DataSourceID = "onePersonDs"
              DataKeyNames = "PersonId">
    <EditItemTemplate>
        ...
        <asp:TextBox runat = "Server"
                     Id = "Name"                                                          
                     Text = '<%# Bind("Name") %>'/>
        ...
        <asp:CustomValidator 
            ID = "UniqueNameValidator"
            runat = "server"
            Display = "Dynamic"
            ControlToValidate = "Name"
            ErrorMessage = "Person already exists!" 
            OnServerValidate = "UniqueNameValidator_ServerValidate" />

Is the best approach to use a custom validator for this? My UniqueNameValidator_ServerValidate looks like this:

public void UniqueNameValidator_ServerValidate(
    object sender, ServerValidateEventArgs e)
{
    // Check for a duplicate.
    var items = from r in db.Persons
                where r.Name == e.Value
                select r;
    e.IsValid = items.Count() == 0;            
}

This works as long as the user tries to change to a different name. But if the user tries to save the form without changing the name, the name will already be found in the database and the validation will prevent the save from taking place.

I'd be happy if someone could point me to some links describing the best way to solve this problem. Despite it being a common scenario, keeping a username unique while still letting the form be submitted, I haven't found any info on how to do it.


Solution

  • Add to where condition comparing FormView's DataKey value to person's PersonId property:

    var items = from r in db.Persons
                where r.Name == e.Value && r.PersonId != (Guid)PersonFormView.DataKey.Value
                select r;