【问题标题】:Downloading a file from SQL Server - ArgumentOutOfRangeException从 SQL Server 下载文件 - ArgumentOutOfRangeException
【发布时间】:2013-04-10 17:39:18
【问题描述】:

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

发生了什么,为什么?

【问题讨论】:

  • gvrow.RowIndex 的值是多少?您是否使用调试器单步执行了代码?
  • @Tim 嗨,gvrow.RowIndex 是 0。
  • 您尝试过stackoverflow.com/questions/6488359/… 中的修复吗?
  • @RandomUs1r 是的,我已将 EnableViewState 设置为 true 无济于事。
  • 公平的,让我看看我是否可以在下面发布解决方案。

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


【解决方案1】:

用这个替换错误行:

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# 开发人员,因此转换可能会有所不同。

【讨论】:

  • Dim selectedRow As Integer = GridView1.SelectedRow.RowIndex 给我这个错误`(NullReferenceException)对象引用未设置为对象的实例。`
  • 请检查:“GridView1.CurrentRow.Index”不是“GridView1.SelectedRow.RowIndex”
【解决方案2】:

通过 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

【讨论】:

  • 嗨。 Wat 将是代码第二部分的 VB.NET 代码吗?
  • 好的,谢谢。而服务器事件将是 Page_Load ?我应该用什么替换“YourDataKeyName”?
  • Server Event 表示 onrowcommand 事件。Yourdatakeyname 表示,你在 gridviw 中有 datakeyname="yourColoumnName",你想在 "yourDataKeyName" 中有这个名字
  • 好的,所以我看到了示例代码并继续执行。只有一个问题,我应该用什么替换&lt;asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None" onrowcommand="GridView1_RowCommand" DataKeyNames="content_id"&gt;中的DataKey
  • 您的数据库表 PrimaryKey 名称
【解决方案3】:

我不久前遇到了这个问题,我自己用数据读取器替换了前辈的数据适配器,原因很明显。

我的解决方法很简单:

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

您还加载了一个数据表,因此应该可以更轻松地进行部署。

在您的具体情况下,原因是没有数据传递到 GV 时引发异常。

【讨论】:

  • 那应该在我的 download() sub 中?
  • 它会去你为你的 gv 绑定数据的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多