ASP .Net: AspNetSqlMembershipProvider “unique emai

2019-07-07 10:09发布

问题:

I am using AspNetSqlMembershipProvider in my ASP .Net 4 web application project.

I have configured user address to be unique (requiresUniqueEmail="true") in my web.config file as below:

<membership>
    <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" 
             type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 
             connectionStringName="MyAuthDB" 
             enablePasswordRetrieval="false" 
             enablePasswordReset="true" 
             requiresQuestionAndAnswer="true" 
             applicationName="/" 
             requiresUniqueEmail="true"
             minRequiredPasswordLength="6" 
             minRequiredNonalphanumericCharacters="1" 
             passwordFormat="Hashed" 
             maxInvalidPasswordAttempts="5" 
             passwordAttemptWindow="10" />
  </providers>
</membership>

But, when I execute the following code with an email already in the database, although new row is not being added to aspnet_Membership table, an entry is being added to: aspnet_Users and aspnet_Profile tables.

Is there any way I can stop these entries from being added to the two tables described above as well?

Here is the code from code behind:

if (Membership.GetUser(EN(this.Id.Value)) != null) {
    this.CustomFieldValidatorId.IsValid = false;
}
else {
    try {
        string username = EN(this.Id.Value);
        string password = EN(this.Password.Value);
        string email = EN(this.Email.Value);
        string question = EN(this.SecurityQuestion.Value);
        string answer = EN(this.Answer.Value);

        string firstname = EN(this.FirstName.Value);
        string lastname = EN(this.LastName.Value);
        DateTime birthdate = new DateTime(
            Convert.ToInt32(EN(this.BirthYear.SelectedValue)),
            Convert.ToInt32(EN(this.BirthMonth.SelectedValue)),
            Convert.ToInt32(EN(this.BirthDay.SelectedValue)));
        string company = EN(this.Company.Value);
        string add1 = EN(this.StreetAddress1.Value);
        string add2 = EN(this.StreetAddress2.Value);
        string city = EN(this.City.Value);
        string state = EN(this.State.Value);
        string zip = EN(this.Zip.Value);
        string country = EN(this.Country.SelectedValue);
        string countrycode = EN(this.CountryCode.Value);
        string areacode = EN(this.AreaCode.Value);
        string phonenum = EN(this.PhoneNumber.Value);
        string extension = EN(this.Extension.Value);

        MembershipCreateStatus S;
        Membership.CreateUser(username, password, email, question, answer, false, out S);

        WebProfile wp = new WebProfile();
        wp.Initialize(username, true);

        wp.PersonalInformation.FirstName = firstname;
        wp.PersonalInformation.LastName = lastname;
        wp.PersonalInformation.BirthDate = birthdate;
        wp.PersonalInformation.Company = company;
        wp.PersonalInformation.StreetAddress1 = add1;
        wp.PersonalInformation.StreetAddress2 = add2;
        wp.PersonalInformation.City = city;
        wp.PersonalInformation.State = state;
        wp.PersonalInformation.Zip = zip;
        wp.PersonalInformation.Country = country;
        wp.PersonalInformation.PhoneCountryCode = countrycode;
        wp.PersonalInformation.PhoneAreaCode = areacode;
        wp.PersonalInformation.PhoneNumber = phonenum;
        wp.PersonalInformation.PhoneExtension = extension;

        wp.Save();

        MembershipUser user = Membership.GetUser(username);
        Roles.AddUserToRole(username, "Developer");
        Membership.UpdateUser(user);

        EmailDeveloper(firstname, lastname, email, (Guid)user.ProviderUserKey);

        this.DeveloperEmail.Text = email;
    }
    catch (MembershipCreateUserException ex) {
        switch (ex.StatusCode) {
            case MembershipCreateStatus.DuplicateEmail:
                this.CustomFieldValidatorEmail.IsValid = false;
                break;
            default:
                this.CustomFieldValidatorGeneral.ErrorMessage = ex.Message.ToString();
                this.CustomFieldValidatorGeneral.IsValid = false;
                break;
        }
    }
}

private string EN(string v) {
    return HttpUtility.HtmlEncode(v.Trim());
}

回答1:

You simply need to check the value of MembershipCreateStatus S; after you attempt to create the user and not fall through to your profile creation code.

That is what it is there for.

e.g.

MembershipCreateStatus S;
Membership.CreateUser(username, password, email, question, answer, false, out S);

if(S != MembershipCreateStatus.Success)
{
   // throw exception or display message and exit here
   // DO NOT PASS GO, DO NOT COLLECT $2000 (adjusted for inflation) 
   // and in NO circumstances fall through to the code below that creates
   // the profile and aspnet_users placeholder record that you mention
}

Reference:

public enum MembershipCreateStatus
{
    Success,
    InvalidUserName,
    InvalidPassword,
    InvalidQuestion,
    InvalidAnswer,
    InvalidEmail,
    DuplicateUserName,
    DuplicateEmail,
    UserRejected,
    InvalidProviderUserKey,
    DuplicateProviderUserKey,
    ProviderError
}