当电子邮件重复时,Membership.CreateUser返回DuplicateUserName

时间:2021-05-23 16:26:59

I have been working on this frustrating bug for a few days now and can not seem to put my finger on it. I am attempting to create a user on an ASP.NET website using the following code:

我已经在这个令人沮丧的bug上工作了几天,似乎无法用手指对它进行操作。我试图使用以下代码在ASP.NET网站上创建用户:

MembershipCreateStatus createStatus;
                                MembershipUser newUser = Membership.CreateUser(UserName.Text, Password1.Text, Email1.Text, SecQ.Text, SecA.Text, true, out createStatus);

                                switch (createStatus)
                                {
                                    case MembershipCreateStatus.Success:
                                        CreateAccountResults.Text = "The user account was successfully created!";
                                        CreateAccountResults.ForeColor = System.Drawing.Color.Green;
                                        break;
                                    case MembershipCreateStatus.DuplicateEmail:
                                        CreateAccountResults.Text = "There already exists a user with this email address.";
                                        break;
                                    case MembershipCreateStatus.DuplicateUserName:
                                        CreateAccountResults.Text = "There already exists a user with this username.";
                                        break;
                                    case MembershipCreateStatus.InvalidEmail:
                                        CreateAccountResults.Text = "There email address you provided in invalid.";
                                        break;
                                    case MembershipCreateStatus.InvalidAnswer:
                                        CreateAccountResults.Text = "There security answer was invalid.";
                                        break;
                                    case MembershipCreateStatus.InvalidPassword:
                                        CreateAccountResults.Text = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character.";
                                        break;
                                    default:
                                        CreateAccountResults.Text = "There was an unknown error; the user account was NOT created.";
                                        break;

However, if I have "Email" a unique column in the database, it will return duplicateUserName if I enter an email address that is already taken (Instead of returning DuplicateEmail) I have attempted to Google and even just read over the code trying to understand the issue but I can not seem to locate exactly where it is going wrong.

但是,如果我在数据库中有“电子邮件”一个唯一列,如果我输入已经采用的电子邮件地址,它将返回duplicateUserName(而不是返回DuplicateEmail)我试图谷歌,甚至只是阅读试图理解的代码问题,但我似乎无法准确找到它出错的地方。

Here is the attached stored procedure called when attempting to create the user:

以下是尝试创建用户时调用的附加存储过程:

    USE [gladiatorial]
GO
/****** Object:  StoredProcedure [dbo].[aspnet_Membership_CreateUser]    Script Date: 07/05/2011 20:40:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[aspnet_Membership_CreateUser]
    @ApplicationName                        nvarchar(256),
    @UserName                               nvarchar(256),
    @Password                               nvarchar(128),
    @PasswordSalt                           nvarchar(128),
    @Email                                  nvarchar(256),
    @PasswordQuestion                       nvarchar(256),
    @PasswordAnswer                         nvarchar(128),
    @IsApproved                             bit,
    @CurrentTimeUtc                         datetime,
    @CreateDate                             datetime = NULL,
    @UniqueEmail                            int      = 0,
    @PasswordFormat                         int      = 0,
    @UserId                                 uniqueidentifier OUTPUT
AS
BEGIN
    DECLARE @ApplicationId uniqueidentifier
    SELECT  @ApplicationId = NULL

    DECLARE @NewUserId uniqueidentifier
    SELECT @NewUserId = NULL

    DECLARE @IsLockedOut bit
    SET @IsLockedOut = 0

    DECLARE @LastLockoutDate  datetime
    SET @LastLockoutDate = CONVERT( datetime, '17540101', 112 )

    DECLARE @FailedPasswordAttemptCount int
    SET @FailedPasswordAttemptCount = 0

    DECLARE @FailedPasswordAttemptWindowStart  datetime
    SET @FailedPasswordAttemptWindowStart = CONVERT( datetime, '17540101', 112 )

    DECLARE @FailedPasswordAnswerAttemptCount int
    SET @FailedPasswordAnswerAttemptCount = 0

    DECLARE @FailedPasswordAnswerAttemptWindowStart  datetime
    SET @FailedPasswordAnswerAttemptWindowStart = CONVERT( datetime, '17540101', 112 )

    DECLARE @NewUserCreated bit
    DECLARE @ReturnValue   int
    SET @ReturnValue = 0

    DECLARE @ErrorCode     int
    SET @ErrorCode = 0

    DECLARE @TranStarted   bit
    SET @TranStarted = 0

    IF( @@TRANCOUNT = 0 )
    BEGIN
        BEGIN TRANSACTION
        SET @TranStarted = 1
    END
    ELSE
        SET @TranStarted = 0

    EXEC dbo.aspnet_Applications_CreateApplication @ApplicationName, @ApplicationId OUTPUT

    IF( @@ERROR <> 0 )
    BEGIN
        SET @ErrorCode = -1
        GOTO Cleanup
    END

    SET @CreateDate = @CurrentTimeUtc

    SELECT  @NewUserId = UserId FROM dbo.aspnet_Users WHERE LOWER(@UserName) = LoweredUserName AND @ApplicationId = ApplicationId
    IF ( @NewUserId IS NULL )
    BEGIN
        SET @NewUserId = @UserId
        EXEC @ReturnValue = dbo.aspnet_Users_CreateUser @ApplicationId, @UserName,  @CreateDate, @NewUserId OUTPUT
        SET @NewUserCreated = 1
    END
    ELSE
    BEGIN
        SET @NewUserCreated = 0
        IF( @NewUserId <> @UserId AND @UserId IS NOT NULL )
        BEGIN
            SET @ErrorCode = 6
            GOTO Cleanup
        END
    END

    IF( @@ERROR <> 0 )
    BEGIN
        SET @ErrorCode = -1
        GOTO Cleanup
    END

    IF( @ReturnValue = -1 )
    BEGIN
        SET @ErrorCode = 10
        GOTO Cleanup
    END

    IF ( EXISTS ( SELECT UserId
                  FROM   dbo.aspnet_Membership
                  WHERE  @NewUserId = UserId ) )
    BEGIN
        SET @ErrorCode = 6
        GOTO Cleanup
    END

    SET @UserId = @NewUserId

    IF (@UniqueEmail = 1)
    BEGIN
        IF (EXISTS (SELECT *
                    FROM  dbo.aspnet_Membership m WITH ( UPDLOCK, HOLDLOCK )
                    WHERE ApplicationId = @ApplicationId AND LoweredEmail = LOWER(@Email)))
        BEGIN
            SET @ErrorCode = 7
            GOTO Cleanup
        END
    END

    IF (@NewUserCreated = 0)
    BEGIN
        UPDATE dbo.aspnet_Users
        SET    LastActivityDate = @CreateDate
        WHERE  @UserId = UserId
        IF( @@ERROR <> 0 )
        BEGIN
            SET @ErrorCode = -1
            GOTO Cleanup
        END
    END

    INSERT INTO dbo.aspnet_Membership
                ( ApplicationId,
                  UserId,
                  Password,
                  PasswordSalt,
                  Email,
                  LoweredEmail,
                  PasswordQuestion,
                  PasswordAnswer,
                  PasswordFormat,
                  IsApproved,
                  IsLockedOut,
                  CreateDate,
                  LastLoginDate,
                  LastPasswordChangedDate,
                  LastLockoutDate,
                  FailedPasswordAttemptCount,
                  FailedPasswordAttemptWindowStart,
                  FailedPasswordAnswerAttemptCount,
                  FailedPasswordAnswerAttemptWindowStart )
         VALUES ( @ApplicationId,
                  @UserId,
                  @Password,
                  @PasswordSalt,
                  @Email,
                  LOWER(@Email),
                  @PasswordQuestion,
                  @PasswordAnswer,
                  @PasswordFormat,
                  @IsApproved,
                  @IsLockedOut,
                  @CreateDate,
                  @CreateDate,
                  @CreateDate,
                  @LastLockoutDate,
                  @FailedPasswordAttemptCount,
                  @FailedPasswordAttemptWindowStart,
                  @FailedPasswordAnswerAttemptCount,
                  @FailedPasswordAnswerAttemptWindowStart )

    IF( @@ERROR <> 0 )
    BEGIN
        SET @ErrorCode = -1
        GOTO Cleanup
    END

    IF( @TranStarted = 1 )
    BEGIN
        SET @TranStarted = 0
        COMMIT TRANSACTION
    END

    RETURN 0

Cleanup:

    IF( @TranStarted = 1 )
    BEGIN
        SET @TranStarted = 0
        ROLLBACK TRANSACTION
    END

    RETURN @ErrorCode

END

I would appreciate it if someone could please point me in the right direction to get this resolve. I have a feeling it is going to be something extremely minor that I have overlooked.

如果有人能指出我正确的方向来获得这个决心,我将不胜感激。我觉得这将是一件非常小的事情,我忽略了。

Thank you.

2 个解决方案

#1


5  

You have to set the attribute requiresUniqueEmail to false in your Web.Config file if you don't want unique emails for users. Eg

如果您不希望用户使用唯一的电子邮件,则必须在Web.Config文件中将attributesUniqueEmail属性设置为false。例如

<membership defaultProvider="SqlProvider"
  userIsOnlineTimeWindow="15">
  <providers>
    <add 
      name="SqlProvider" 
      type="System.Web.Security.SqlMembershipProvider" 
      connectionStringName="SqlServices"
      applicationName="MyApplication"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="true"
      requiresUniqueEmail="false"
      passwordFormat="Hashed"
      maxInvalidPasswordAttempts="5"
      passwordAttemptWindow="10" />
  </providers>
</membership>

#2


0  

The stored procedure checks whether a record with that user name exists before checking the email address. If you are using the email address as the user name, it returns a value corresponding to MembershipCreateStatus.DuplicateUserName and never gets around to checking the email address.

存储过程在检查电子邮件地址之前检查是否存在具有该用户名的记录。如果您使用电子邮件地址作为用户名,它将返回与MembershipCreateStatus.DuplicateUserName对应的值,并且永远不会检查电子邮件地址。

#1


5  

You have to set the attribute requiresUniqueEmail to false in your Web.Config file if you don't want unique emails for users. Eg

如果您不希望用户使用唯一的电子邮件,则必须在Web.Config文件中将attributesUniqueEmail属性设置为false。例如

<membership defaultProvider="SqlProvider"
  userIsOnlineTimeWindow="15">
  <providers>
    <add 
      name="SqlProvider" 
      type="System.Web.Security.SqlMembershipProvider" 
      connectionStringName="SqlServices"
      applicationName="MyApplication"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="true"
      requiresUniqueEmail="false"
      passwordFormat="Hashed"
      maxInvalidPasswordAttempts="5"
      passwordAttemptWindow="10" />
  </providers>
</membership>

#2


0  

The stored procedure checks whether a record with that user name exists before checking the email address. If you are using the email address as the user name, it returns a value corresponding to MembershipCreateStatus.DuplicateUserName and never gets around to checking the email address.

存储过程在检查电子邮件地址之前检查是否存在具有该用户名的记录。如果您使用电子邮件地址作为用户名,它将返回与MembershipCreateStatus.DuplicateUserName对应的值,并且永远不会检查电子邮件地址。