无法重定向尝试使用WebClient下载文件

时间:2014-08-29 20:34:01

标签: asp.net vb.net

如何从aspx页面下载文件并绕过保存文件对话框?

我正在尝试从网页下载文件并遇到问题。我们的想法是避免响应保存文件对话框,只是将文件直接保存到我的电脑上。

网页需要凭据。所以我目前正在使用WebBrowser控件登录并导航到具有生成下载按钮的页面。然后我使用代码here(代码有16个ish upvotes,基本上使用来自#34; wininet.dll&#34的InternetGetCookieEx来提取cookie)。

使用Fiddler2,我可以看到按下按钮会生成POST请求。我模仿下面的请求。

到目前为止,我正在尝试使用我的代码:

    Dim testUri As New Uri(WebBrowser1.Url.ToString)

    request = WebRequest.Create(WebBrowser1.Url.ToString)

    Dim c = Cookies.GetUriCookieContainer(testUri)

    With request
        .Method = "POST"
        .Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
        .UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E)"
        .CookieContainer = Cookies.GetUriCookieContainer(testUri)
        .ContentLength = 0
        .ContentType = "application/x-www-form-urlencoded"
        .AllowAutoRedirect = True
    End With

    Dim response = request.GetResponse

    Console.WriteLine(response.ResponseUri)
    Console.WriteLine(response.ContentType)

    Dim wc As New WebClient
    wc.Headers.Add(HttpRequestHeader.Cookie, c.GetCookieHeader(response.ResponseUri))
    wc.DownloadFile(response.ResponseUri, "C:\report.xls")

Cookies是我写的一个类,用于保存链接中的代码(下面,如果它不起作用)     进口System.Net     Imports System.Text

Public Class Cookies
    <Runtime.InteropServices.DllImport("wininet.dll")> _
Private Shared Function InternetGetCookieEx(ByVal url As String, ByVal cookieName As String, _
                                     ByVal cookieData As StringBuilder, ByRef size As Integer, _
                                     ByVal dwFlags As Int32, ByVal lpReserved As IntPtr) As Boolean
    End Function

    Const InternetCookieHttponly As Int32 = &H2000

    Public Shared Function GetUriCookieContainer(ByVal uri As Uri) As CookieContainer

        Dim cookies As CookieContainer = Nothing
        Dim datasize As Integer = 8192 * 16

        Dim cookieData As StringBuilder = New StringBuilder(datasize)

        If Not InternetGetCookieEx(uri.ToString, Nothing, cookieData, datasize, InternetCookieHttponly, IntPtr.Zero) Then

            If datasize < 0 Then
                Return Nothing
            End If

            cookieData = New StringBuilder(datasize)
            If Not InternetGetCookieEx(uri.ToString, Nothing, cookieData, datasize, InternetCookieHttponly, IntPtr.Zero) Then
                Return Nothing
            End If

        End If

        If cookieData.Length > 0 Then
            cookies = New CookieContainer
            cookies.SetCookies(uri, cookieData.ToString.Replace(";", ","))

            'Console.WriteLine(cookieData.ToString.Replace(";", ","))

        End If

        Return cookies

    End Function

End Class

设置cookie工作正常,但我的实际请求并没有返回预期的数据,它只是保存了我的网页副本(时髦,因为我试图用excel打开它。如果我将它保存为文本,我将HTML放到整个页面上。)

按钮页面上的代码似乎没有指向任何内容。我找不到任何对列出的jQuery的引用 - 我可能不得不模仿它?

<td align="center" id="excel_cell" noWrap="nowrap" style="width: 50px;">
    <input name="xcel" title="Send report to excel" id="xcel" style="background-image: url(../resx/images/excel.png); BORDER-BOTTOM: medium none; border-left: medium none; background-color: transparent; width: 32px; background-repeat: no-repeat; height: 32px; border-top: medium none; cursor: pointer; border-right: medium none;" type="button" jQuery1710025381725129178523="48"/>
        Text - Empty Text Node

我尝试过&#34;点击&#34; web浏览器中的按钮

WebBrowser1.Document.Window.Document.GetElementById("xcel").InvokeMember("click")

但是我试图隐藏用户的保存文件对话框并自动完成整个过程。

任何帮助都会非常受欢迎!

编辑:修正了!

解决方案 - 我需要添加到标题中,另外,我需要更正我的POST数据

    Dim postData As String = xxxx
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
    Dim dataStream As Stream = request.GetRequestStream

    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()

1 个答案:

答案 0 :(得分:0)

我假设从目前为止提供的信息中没有需要包含在POST中的字段。如果是这种情况,我建议您与Fiddler进行更深入的合作,将您的代码所做的请求与在Web浏览器中手动执行时所做的请求进行比较。可能是您需要发送服务器端代码正在检查的其他标头。如果存在差异,并且您可以优化代码,直到它100%模拟手动请求的样子,那么您很有可能通过消除过程来解决这个问题。

您可能会发现,例如,他们正在寻找要设置的“referer”标头。在这种情况下,在标题代码中添加另一行:

wc.Headers.Add("Referer", yourReferringUrl);