0

我正在尝试使用 GridView 从 SQL Server 2012 数据库下载文件。我收到了ArgumentOutOfRangeException这个错误:

Index was out of range. Must be non-negative and less than the size of the collection.

上:

Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())

相关代码:

 Protected Sub lnkDownload_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim lnkbtn As LinkButton = TryCast(sender, LinkButton)
        Dim gvrow As GridViewRow = TryCast(lnkbtn.NamingContainer, GridViewRow)
        Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())
        Dim name As String, type As String
        Dim con As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")

        con.Open()



        Using cmd As New SqlCommand()
            cmd.CommandText = "Select content_name, content_type, content_file from content where content_id=@Id"
            cmd.Parameters.AddWithValue("@Id", fileid)
            cmd.Connection = con
            con.Open()

            Dim dt As DataTable = GetData(cmd)

            If dt IsNot Nothing Then

                download(dt)

            End If

        End Using

    End Sub


    Public Function GetData(ByVal cmd As SqlCommand) As DataTable

        Dim dt As New DataTable

        Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()

        Dim con As New SqlConnection(strConnString)

        Dim sda As New SqlDataAdapter

        cmd.CommandType = CommandType.Text

        cmd.Connection = con

        Try

            con.Open()

            sda.SelectCommand = cmd

            sda.Fill(dt)

            Return dt

        Catch ex As Exception

            Response.Write(ex.Message)

            Return Nothing

        Finally

            con.Close()

            sda.Dispose()

            con.Dispose()

        End Try

    End Function


    Protected Sub download(ByVal dt As DataTable)

        Dim bytes() As Byte = CType(dt.Rows(0)("Data"), Byte())

        Response.Buffer = True

        Response.Charset = ""

        Response.Cache.SetCacheability(HttpCacheability.NoCache)

        Response.ContentType = dt.Rows(0)("ContentType").ToString()

        Response.AddHeader("content-disposition", "attachment;filename=" & dt.Rows(0)("Name").ToString())

        Response.BinaryWrite(bytes)

        Response.Flush()

        Response.End()

    End Sub

gvrow.RowIndex 调试时为0

完整代码:

导入 System.Data.SqlClient 导入 System.Data 导入 System.IO

Partial Class Documents
    Inherits System.Web.UI.Page

    Protected Sub btnUploadContent_Click(sender As Object, e As EventArgs) Handles btnUploadContent.Click

        Dim filePath As String = FileUpload.PostedFile.FileName

        Dim filename As String = Path.GetFileName(filePath)

        Dim ext As String = Path.GetExtension(filename)

        Dim contenttype As String = String.Empty



        Select Case ext

            Case ".doc"

                contenttype = "application/vnd.ms-word"

                Exit Select

            Case ".docx"

                contenttype = "application/vnd.ms-word"

                Exit Select

            Case ".xls"

                contenttype = "application/vnd.ms-excel"

                Exit Select

            Case ".xlsx"

                contenttype = "application/vnd.ms-excel"

                Exit Select

            Case ".jpg"

                contenttype = "image/jpg"

                Exit Select

            Case ".png"

                contenttype = "image/png"

                Exit Select

            Case ".gif"

                contenttype = "image/gif"

                Exit Select

            Case ".pdf"

                contenttype = "application/pdf"

                Exit Select

        End Select

        If contenttype <> String.Empty Then

            Dim fs As Stream = FileUpload.PostedFile.InputStream

            Dim br As New BinaryReader(fs)

            Dim bytes As Byte() = br.ReadBytes(fs.Length)



            'insert the file into database


            Dim strQuery As String = "INSERT INTO [master_db].[dbo].[content] ([content_name],[content_type],[content_file]) VALUES (@Name, @ContentType, @Data)"
            Dim cmd As New SqlCommand(strQuery)

            cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = filename

            cmd.Parameters.Add("@ContentType", SqlDbType.VarChar).Value() = contenttype

            cmd.Parameters.Add("@Data", SqlDbType.Binary).Value = bytes

            InsertUpdateData(cmd)

            lblMessage.ForeColor = System.Drawing.Color.Green

            lblMessage.Text = "File Uploaded Successfully"

        Else

            lblMessage.ForeColor = System.Drawing.Color.Red

            lblMessage.Text = "File format not recognised." + " Upload Image/Word/PDF/Excel formats"

        End If

    End Sub

    Protected Sub lnkDownload_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim lnkbtn As LinkButton = TryCast(sender, LinkButton)
        Dim gvrow As GridViewRow = TryCast(lnkbtn.NamingContainer, GridViewRow)
        Dim fileid As Integer = Convert.ToInt32(GridView1.DataKeys(gvrow.RowIndex).Value.ToString())
        Dim name As String, type As String
        Dim con As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")

        con.Open()



        Using cmd As New SqlCommand()
            cmd.CommandText = "Select content_name, content_type, content_file from content where content_id=@Id"
            cmd.Parameters.AddWithValue("@Id", fileid)
            cmd.Connection = con
            con.Open()

            Dim dt As DataTable = GetData(cmd)

            If dt IsNot Nothing Then

                download(dt)

            End If

        End Using

    End Sub


    Public Function GetData(ByVal cmd As SqlCommand) As DataTable

        Dim dt As New DataTable

        Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()

        Dim con As New SqlConnection(strConnString)

        Dim sda As New SqlDataAdapter

        cmd.CommandType = CommandType.Text

        cmd.Connection = con

        Try

            con.Open()

            sda.SelectCommand = cmd

            sda.Fill(dt)

            Return dt

        Catch ex As Exception

            Response.Write(ex.Message)

            Return Nothing

        Finally

            con.Close()

            sda.Dispose()

            con.Dispose()

        End Try

    End Function


    Protected Sub download(ByVal dt As DataTable)

        Dim bytes() As Byte = CType(dt.Rows(0)("Data"), Byte())

        Response.Buffer = True

        Response.Charset = ""

        Response.Cache.SetCacheability(HttpCacheability.NoCache)

        Response.ContentType = dt.Rows(0)("ContentType").ToString()

        Response.AddHeader("content-disposition", "attachment;filename=" & dt.Rows(0)("Name").ToString())

        Response.BinaryWrite(bytes)

        Response.Flush()

        Response.End()

    End Sub



    Public Function InsertUpdateData(ByVal cmd As SqlCommand) As Boolean

        Dim strConnString As String = System.Configuration.ConfigurationManager.ConnectionStrings("ConnStringDb1").ConnectionString()

        Dim conn As New SqlConnection("Data Source=BRIAN-PC\SQLEXPRESS;Initial Catalog=master_db;Integrated Security=True;")

        cmd.CommandType = CommandType.Text

        cmd.Connection = conn

        Try

            conn.Open()

            cmd.ExecuteNonQuery()

            Return True

        Catch ex As Exception

            Response.Write(ex.Message)

            Return False

        Finally

            conn.Close()

            conn.Dispose()

        End Try

    End Function

End Class

发生了什么,为什么?

4

3 回答 3

0

通过 CommandArgument 传递 RowIndex 并使用它来检索 DataKey 值

在 Button 上添加以下行

CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'

并在服务器事件上添加以下行

    Dim Index As Integer = Integer.Parse(e.CommandArgument.ToString())
    Dim val As String = DirectCast(Me.grid.DataKeys(Index)("YourDataKeyName"), String)

更新:

请参阅此示例:

样品1

样品 2

于 2013-04-10T17:59:22.860 回答
0

出于显而易见的原因,我前段时间自己用数据读取器替换了前辈数据适配器时遇到了这个问题。

我的解决方法很简单:

if (dt.Rows.Count == 0)
//do stuff
else
//do nothing
GV.DataSource = new DataTable();

您还加载了一个数据表,因此应该更容易部署它。

在您的特定情况下,原因是当没有数据传递给 GV 时会引发异常。

于 2013-04-10T20:20:34.053 回答
0

用这个替换错误行:

Dim selectedRow As Integer = Me.GridView1.CurrentRow.Index

Dim fileid As Integer = Convert.ToInt32(Me.GridView1.Item(1,gvrow.RowIndex).Value.ToString())

将数字 1 替换为包含 fileid 的单元格的索引(即,如果第一个单元格为 0,第二个单元格为 1,依此类推)

让我知道这个是否奏效。我是 C# 开发人员,因此转换可能会有所不同。

于 2013-04-10T17:57:24.517 回答