Edward Mergel Ответов: 1

Сведения об исключении: system. indexoutofrangeexception: в позиции 0 нет строки


Я не могу понять, что я делаю неправильно. Я пытаюсь вставить новый вопрос в базу данных access, и участник, задающий этот вопрос, получает 1 балл, добавленный к их баллам в таблице Points, в то время как вопрос вставляется в таблицу questionList.

There is no row at position 0.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.IndexOutOfRangeException: There is no row at position 0.

Source Error: 


Line 25:                 Dim pointCnt As New DataTable
Line 26:                 Dim QID As String = ran.Next(0, TextBox1.Text.Length)
Line 27:                 Dim pnt As Integer = pointCnt.Rows(0)(0) + 1
Line 28:                 Dim Points As Integer
Line 29: 

Source File: E:\hosting\blueeyeweb\postNewQuestion.aspx.vb    Line: 27 

Stack Trace: 


[IndexOutOfRangeException: There is no row at position 0.]
   System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex) +1547970
   System.Data.RBTree`1.get_Item(Int32 index) +19
   System.Data.DataRowCollection.get_Item(Int32 index) +11
   postNewQuestion.Button1_Click(Object sender, EventArgs e) in E:\hosting\blueeyeweb\postNewQuestion.aspx.vb:27
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565


Что я уже пробовал:

Imports System.Data.OleDb
Imports System.Data

Partial Class postNewQuestion
    Inherits System.Web.UI.Page

    Dim dap, pointDs As OleDbDataAdapter
    Dim con As OleDbConnection
    Dim com As New OleDbCommand
    Dim invalid() As String = {"<h1>", "<script>", "<h2>", "<input", "<h3>", "<a", "<h4>"}
    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Button1.Text = "Ask Question" Then
            If TextBox1.Text <> "" Then
                For Each s As String In invalid
                    If TextBox1.Text.ToLower.Contains(s) = True Then
                        errMessage.Text = Server.HtmlEncode("Cannot Contain <h1>,<Script>,<input>,<a> etc tags")
                        Exit Sub
                    End If
                Next

                con = New OleDbConnection("Provider=Microsoft.Jet.Oledb.4.0 ;data source=" & Server.MapPath("app_data/SimpleQSet.mdb") & ";")

                com.Connection = con
                Session("member") = "420Man"

                Dim ran As New Random
                Dim pointCnt As New DataTable
                Dim QID As String = ran.Next(0, TextBox1.Text.Length)
                Dim pnt As Integer = pointCnt.Rows(0)(0) + 1
                Dim Points As Integer

                Try

                    com.CommandText = "insert into QuestionList values('" + QID + "','" + TextBox1.Text + "','" + DropDownList1.SelectedValue + "','" + DateTime.Now.ToShortDateString() + "','" + Session("member") + "')"
                    con.Open()
                    com.ExecuteNonQuery()


                Catch ex As Exception
                    pointDs = New OleDbDataAdapter("select Points from Points where Member='" + Session("member") + "'", con)
                    pointDs.Fill(pointCnt)

                    Using cmd = New OleDbCommand()
                        com.CommandText = "update [Points]=@Points set Points='" & pnt & "' where Member='" & Session("member") & "'"

                        cmd.Parameters.AddWithValue("@Points", Points)
                        com.ExecuteNonQuery()
                    End Using
                Finally

                End Try

                con.Dispose()
                con.Close()
            Else
                errMessage.Text = "Question Cannot Be Blank"
                TextBox1.Focus()
            End If
        Else
            Response.Redirect("postNewQuestion-Confirmed.aspx")
        End If
        con.Dispose()
        con.Close()

    End Sub

1 Ответов

Рейтинг:
4

OriginalGriff

Для начала, не делай этого так! Никогда не объединяйте строки для построения SQL-команды. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку с точки зрения SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x'; DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

А потом посмотрите на свой код:
Dim pointCnt As New DataTable
                Dim QID As String = ran.Next(0, TextBox1.Text.Length)
                Dim pnt As Integer = pointCnt.Rows(0)(0) + 1

Вы создаете DataTable, но не даете ему никаких строк или столбцов: поэтому, когда вы пытаетесь получить к ним доступ, там ничего нет.
Вероятно, вы хотите прочитать значение из базы данных, но, честно говоря, я не уверен - этот код не выглядит так, как будто о нем слишком много думали до того, как он был написан, и это немного ... случайный... в том, что он делает.