0

我使用了msdn.microsoft.com/en-us/library/ms366730.aspx上的自定义成员资格提供程序,并进行了一些更改以适合我的用户数据库。在 GetUser 方法中,它使用 SqlDataReader 并抛出:

System.IndexOutOfRangeException:索引超出了数组的范围。

那么是什么决定了数组的大小呢?我假设它是 SQL SELECT 语句,并且有 12 个项目,所以reader.GetBoolean(11)应该是最后一个索引,对吧?

private NCCMembershipUser GetUserFromReader(SqlDataReader reader)
    {

        object providerUserKey = reader.GetValue(0);
        string username = reader.GetString(1);
        string email = username;
        string passwordQuestion = "";
        string comment = "";


        // 0 UserID, 1 Email, 2 PasswordQuestion,
        // 3 Comment, 4 IsApproved, 5 IsLockedOut, 6 CreationDate, 7 LastLoginDate,
        // 8 LastActivityDate, 9 LastPasswordChangedDate, 10 LastLockedOutDate, 11 IsSubscribed

        bool isApproved = reader.GetBoolean(4);
        bool isLockedOut = reader.GetBoolean(5);
        bool isSubscribed = reader.GetBoolean(11);// <--- ****HERE****

        DateTime creationDate = reader.GetDateTime(6);
        DateTime lastLoginDate = new DateTime();
        DateTime lastActivityDate = reader.GetDateTime(8);
        DateTime lastPasswordChangedDate = reader.GetDateTime(9);
        DateTime lastLockedOutDate = new DateTime(10);

        if (reader.GetValue(2) != DBNull.Value)
            passwordQuestion = reader.GetString(2);

        if (reader.GetValue(3) != DBNull.Value)
            comment = reader.GetString(3);


        if (reader.GetValue(7) != DBNull.Value)
            lastLoginDate = reader.GetDateTime(7);

        if (reader.GetValue(10) != DBNull.Value)
            lastLockedOutDate = reader.GetDateTime(10);

        NCCMembershipUser u = new NCCMembershipUser(this.Name,
                                                      username,
                                                      providerUserKey,
                                                      email,
                                                      passwordQuestion,
                                                      comment,
                                                      isApproved,
                                                      isLockedOut,
                                                      creationDate,
                                                      lastLoginDate,
                                                      lastActivityDate,
                                                      lastPasswordChangedDate,
                                                      lastLockedOutDate,
                                                      isSubscribed);

        return u;
    }

从 GetUser 调用该方法:

    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        SqlConnection conn = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand("SELECT UserID, Email, PasswordQuestion," +
            " Comment, IsApproved, IsLockedOut, CreationDate, LastLoginDate," +
            " LastActivityDate, LastPasswordChangedDate, LastLockedOutDate" +
            " IsSubscribed" +
            " FROM Users WHERE Email = @Email AND ApplicationName = @ApplicationName", conn);

        cmd.Parameters.Add("@Email", SqlDbType.NVarChar, 128).Value = username;
        cmd.Parameters.Add("@ApplicationName", SqlDbType.NVarChar, 255).Value = m_ApplicationName;

        NCCMembershipUser u = null;
        SqlDataReader reader = null;

        try
        {
            conn.Open();

            reader = cmd.ExecuteReader();

            if (reader.HasRows)
            {
                reader.Read();
                u = GetUserFromReader(reader);

                if (userIsOnline)
                {
                    SqlCommand updateCmd = new SqlCommand("UPDATE Users " +
                        "SET LastActivityDate = @LastActivityDate " +
                        "WHERE Email = @Email AND ApplicationName = @ApplicationName", conn);

                    updateCmd.Parameters.Add("@LastActivityDate", SqlDbType.DateTime).Value = DateTime.Now;
                    updateCmd.Parameters.Add("@Email", SqlDbType.VarChar, 255).Value = username;
                    updateCmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = m_ApplicationName;

                    updateCmd.ExecuteNonQuery();
                }
            }

        }
        catch (SqlException e)
        {
            if (WriteExceptionsToEventLog)
            {
                WriteToEventLog(e, "GetUser(String, Boolean)");

                throw new ProviderException(exceptionMessage);
            }
            else
            {
                throw e;
            }
        }
        finally
        {
            if (reader != null) { reader.Close(); }

            conn.Close();
        }

        return u;
    }
4

1 回答 1

3

我注意到你的 SQL在 LastLockedOutDate 和 IsSubscribed 之间没有。

于 2012-06-03T01:25:06.070 回答