从SQL Server下载文件 - ArgumentOutOfRangeException

时间:2013-04-10 17:39:18

标签: asp.net vb.net gridview download sql-server-2012

我正在尝试使用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     Imports 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

发生了什么以及为什么?

3 个答案:

答案 0 :(得分: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#开发人员,因此转换可能会有所不同。

答案 1 :(得分:0)

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

在按钮上添加以下行

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)

<强>更新

请参阅此示例:

sample1

sample 2

答案 2 :(得分:0)

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

我的修复很简单:

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

您还要加载数据表,这样可以更轻松地部署它。

在特定情况下,原因是没有数据传递给GV时会抛出异常。

相关问题