На работе мы заходим на сайт провайдера, который служит хранилищем файлов.Появится список файлов.Каждое имя файла является ссылкой.Нажмите на ссылку и загрузите файл.Это очень легкий веб-сайт.
Я пытаюсь войти в систему и загрузить файлы без утомительной задачи щелкать по каждому из них (флажок «выбрать все» отсутствует).Для начала я использую элемент управления WebBrowser в форме с кнопкой «Перейти».Вот кодПожалуйста, перейдите к ряду звездочек.
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
Try
PageLoaded = False
browser.Navigate("https://[the website]/Account/Login.htm", False)
While Not PageLoaded
Application.DoEvents()
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
Try
browser.Document.GetElementById("username").InnerText = [username]
browser.Document.GetElementById("password").InnerText = [password]
PageLoaded = False
browser.Document.Forms("mainform").InvokeMember("submit")
While Not PageLoaded
Application.DoEvents()
End While
Catch ex As Exception
MsgBox(ex.Message)
End Try
' ************************************
Dim mycookies As String
mycookies = browser.Document.Cookie
' DEBUG: verified cookies are indeed present
Try
Dim cookieJar As New CookieContainer
Dim cookies As String() = browser.Document.Cookie.Split({"; "}, StringSplitOptions.RemoveEmptyEntries)
Dim cookievaluepairs() = cookies(0).Split("=")
Dim cky As New Cookie(cookievaluepairs(0), cookievaluepairs(1))
cky.Domain = browser.Document.Domain
cookieJar.Add(cky)
Dim cookievaluepairs1() = cookies(1).Split("=")
Dim cky1 As New Cookie(cookievaluepairs(0), cookievaluepairs(1))
cky1.Domain = browser.Document.Domain
cookieJar.Add(cky1)
' DEBUG: verified cookieJar contains expected cookies
Dim wwwclient As New CookieAwareWebClient(cookieJar)
' DEBUG: please see class code below
Dim x As Integer
Dim dlurl As String = ""
Dim inputs As HtmlElementCollection = browser.Document.Links
For Each elm As HtmlElement In inputs
If Microsoft.VisualBasic.Left(elm.OuterHtml, 10) = "<A href=""/" Then
dlurl = elm.GetAttribute("href")
' DEBUG: crappily named dlurl indeed has correct URI
wwwclient.DownloadFile(dlurl, "D:\Desktop\file" & x)
' DEBUG: overriden function GetWebRequest fires
' please see class code below
End If
Next
Catch ex As Exception
MsgBox(ex.Message)
' DEBUG: always lands here with 401 error
End Try
End Sub
Вот одна из многих версий CookieAwareWebClient, найденных здесь на SO.
Public Class CookieAwareWebClient
Inherits WebClient
Private m_container As CookieContainer = New CookieContainer()
Public Sub New(cc As CookieContainer)
m_container = cc
' DEBUG: verified m_container now has cookieJar passed as cc
End Sub
Protected Overrides Function GetWebRequest(ByVal address As Uri) As WebRequest
Dim request As WebRequest = MyBase.GetWebRequest(address)
Dim webRequest As HttpWebRequest = TryCast(request, HttpWebRequest)
If webRequest IsNot Nothing Then
webRequest.CookieContainer = m_container
End If
Return webRequest
' DEBUG: verified webRequest.CookieContainer is correct
End Function
End Class
Я пошагово перебираю код полностьюв оператор wwwclient.DownloadFile
, затем через код в функции GetWebRequest и после паузы я получаю 401 Not Authorized.Это произошло с пятью или шестью вариантами CookieAwareWebClient, которые я обнаружил.
Два куки, которые я извлекаю из элемента управления WebBrowser после успешного входа в систему, выглядят так (каждый раз по разным токенам).
"samlssologgedout=SSO%20Logged%20Out"
"token=A4AA416E-46C8-11e9-92CD-005056A005E4"
Я проверил, что это те же самые куки, которые входят в 'webRequest.CookieContainer'.Кроме того, в элементе управления WebBrowser после входа в систему можно щелкнуть ссылку на файл, чтобы загрузить его.
Кто-нибудь видит что-то явно неправильное в коде?
Продолжая гуглить во время написания вопроса, я только что наткнулся на Примечания для наследников в документации MS для WebClient - «Производные классы должны вызывать реализацию базового класса WebClient, чтобы гарантировать, что производный класс работает должным образом».
Это звучит как то, что вы бы сделали в конструкторе?Или об этом позаботились в утверждении MyBase.GetWebRequest(address)
?