SqlDataReader异常:索引超出了数组的范围

时间:2012-06-03 01:16:31

标签: c# asp.net membership-provider

我在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;
    }

1 个答案:

答案 0 :(得分:3)

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