SqlDataReader 异常:索引超出数组的边界

本文关键字:数组 边界 异常 索引 SqlDataReader | 更新日期: 2023-09-27 18:36:04

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

System.IndexOutOfRangeException:Index 在数组的边界之外。

那么是什么决定了数组的大小呢?我假设它是 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;
    }

SqlDataReader 异常:索引超出数组的边界

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