2010-01-07 21 views
0

我試着搜索並發現有人寫了一個多部分形式的上傳。VB.NET - 多部分表單上傳不起作用。怎麼了?

雖然它有一件事是錯誤的:它轉移了所有的 - 據推測 - 在URL中的POST值。哪個Web應用程序不喜歡 - 以某種方式。

它走遍

POST /index.php?page=post&s=add&title=test&tags=testtags HTTP/1.1

而且只添加的文件進入後內容。

我試圖用瀏覽器提交,這出來:

POST /index.php?page=post&s=add HTTP/1.1 
Host: gelbooru.com 

Connection: keep-alive 
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.0 (KHTML, like Gecko) Chrome/3.0.195.38 Safari/532.0 
Referer: http://gelbooru.com/index.php?page=post&s=add 
Content-Length: 54851 
Cache-Control: max-age=0 
Origin: http://gelbooru.com 
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFqdVQ+1blrPMX2py 
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 
Accept-Encoding: gzip,deflate,sdch 
Cookie: __utmz=52483902.1258558959.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);user_id=7382; pass_hash=lolpasswordcensored; __utma=52483902.1527465380.1258558959.1261431208.1261504455.7; __utmc=52483902; __utmb=52483902.1.10.1261504455 
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="upload"; filename="001.jpg" 
Content-Type: image/jpeg 

IMGDATA 
------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="source" 


------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="title" 


------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="tags" 

tagtests 
------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="rating" 

e 
------WebKitFormBoundaryFqdVQ+1blrPMX2py 
Content-Disposition: form-data; name="submit" 

Upload 
------WebKitFormBoundaryFqdVQ+1blrPMX2py-- 

我替換IMGDATA圖像數據字節,使其更短。

此上傳被接受。所以我試圖用我將很快展示的VB.NET代碼來模仿這個。 This out out:

POST /index.php?page=post&s=add& HTTP/1.1 
Cookie: user_id=7382; pass_hash=lolpass_hashcensor; 
Origin: http://gelbooru.com 
Referer: http://gelbooru.com/index.php?page=post&s=add 
Content-Type: multipart/form-data; boundary=----------8cc5152e90b3c60 
Host: gelbooru.com 
Content-Length: 243397 
Expect: 100-continue 
Connection: Keep-Alive 


HTTP/1.1 100 Continue 


----------8cc5152e90b3c60 
Content-Disposition: form-data; name="tags" 

tagtest 
----------8cc5152e90b3c60 
Content-Disposition: form-data; name="source" 


----------8cc5152e90b3c60 
Content-Disposition: form-data; name="rating" 

e 
----------8cc5152e90b3c60 
Content-Disposition: form-data; name="title" 


----------8cc5152e90b3c60 
Content-Disposition: form-data; name="submit" 

Upload 
----------8cc5152e90b3c60 
Content-Disposition: form-data; name="upload"; filename="1017E.jpg" 
Content-Type: application/octet-stream 

FILE 
----------8cc5152e90b3c60 

雖然這不被接受。那麼問題是什麼?我也嘗試把兩個額外的( - )放在別的地方。最後,它沒有改變任何東西。這是我用於傳輸的VB.NET代碼的缺失。 Uploader.Start通過使用全局變量的線程開始上傳過程。

Sub StartUploadJob(ByVal filepath As String, ByVal tags As String, ByVal title As String, ByVal source As String, ByVal rate As rating) 
    ContinueProgressLoop = True 
    processloop = New Threading.Thread(AddressOf ProgressLoopThread) 
    Uploader = New Threading.Thread(AddressOf UploadFileEx) 
    uploadfile = filepath 

    querystring("page") = "post" 
    querystring("s") = "add" 
    'http://gelbooru.com/index.php?page=dapi&s=post&q=index 
    'querystring("page") = "dapi" 
    'querystring("s") = "post" 
    'querystring("q") = "index" 
    'url = "http://gelbooru.com/index.php" 
    url = "http://sinni800.ath.cx/UploadTest.aspx" 
    'url = "http://gelbooru.com/ok.php" 
    fileFormName = "upload" 
    contenttype = "application/octet-stream" 
    uploadstrings("tags") = tags 
    uploadstrings("source") = source 
    uploadstrings("rating") = rate.ToString 
    uploadstrings("title") = title 
    'querystring("user_id") = My.Settings("user_id") 
    'querystring("pass_hash") = My.Settings("pass_hash") 
    uploadstrings("submit") = "Upload" 
    working = True 
    cookies = New CookieContainer() 
    'cookies.Add(My.Settings.cookies) 
    Uploader.Start() 
    processloop.Start() 

End Sub 

Dim uploadstrings As New NameValueCollection 
Dim uploadfile As String : Dim url As String : Dim fileFormName As String : Dim contenttype As String : Dim querystring As New NameValueCollection : Dim cookies As CookieContainer 
Function UploadFileEx() '(ByVal uploadfile As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As NameValueCollection, ByVal cookies As CookieContainer) As String 
    If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then 
     fileFormName = "file" 
    End If 

    If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then 
     contenttype = "application/octet-stream" 
    End If 


    Dim postdata As String 
    postdata = "?" 
    If querystring IsNot Nothing Then 
     For Each key As String In querystring.Keys 
      postdata += (key & "=") + querystring.[Get](key) & "&" 
     Next 
    End If 
    Dim uri As New Uri(url + "?page=post&s=add") 


    Dim boundary As String = "----------" & DateTime.Now.Ticks.ToString("x") 
    Dim webrequest__1 As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest) 
    'webrequest__1.CookieContainer = cookies 
    webrequest__1.Headers(HttpRequestHeader.Cookie) = My.Settings.cookie_string 
    webrequest__1.Headers.Add("Origin", "http://gelbooru.com") 
    webrequest__1.Referer = "http://gelbooru.com/index.php?page=post&s=add" 
    webrequest__1.ContentType = "multipart/form-data; boundary=" & boundary 
    webrequest__1.Method = "POST" 


    ' Build up the post message header 
    Dim sb As New StringBuilder() 

    For Each key As String In uploadstrings.Keys 
     ' content-disposition: form-data; name="field1" 
     'content-type: text/plain 

     sb.Append(boundary & vbCrLf) 
     sb.Append("Content-Disposition: form-data; name=""" + key + """" & vbCrLf) 
     ' sb.Append("content-type: text/plain" & vbCrLf) 
     sb.Append(vbCrLf) 
     sb.Append(uploadstrings(key)) 
     sb.Append(vbCrLf) 

    Next 

    Dim close As Byte() = Encoding.UTF8.GetBytes("--") 

    sb.Append("--") 
    sb.Append(boundary) 
    sb.Append(vbCr & vbLf) 
    sb.Append("Content-Disposition: form-data; name=""") 
    sb.Append(fileFormName) 
    sb.Append("""; filename=""") 
    sb.Append(Path.GetFileName(uploadfile)) 
    sb.Append("""") 
    sb.Append(vbCr & vbLf) 
    sb.Append("Content-Type: ") 
    sb.Append(contenttype) 
    sb.Append(vbCr & vbLf) 
    sb.Append(vbCr & vbLf) 

    Dim postHeader As String = sb.ToString() 
    Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader) 

    ' Build the trailing boundary string as a byte array 
    ' ensuring the boundary appears on a line by itself 
    Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes(vbCr & vbLf & boundary & "--" & vbCr & vbLf) 

    Dim fileStream As New FileStream(uploadfile, FileMode.Open, FileAccess.Read) 
    Dim length As Long = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length 
    webrequest__1.ContentLength = length 

    Dim requestStream As Stream = webrequest__1.GetRequestStream() 

    Dim fulllength As Integer = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length 

    RaiseEvent TextMessage("") 

    ' Write out our post header 
    RaiseEvent TextMessage("Write out our post header") 
    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length) 
    progress = New Progress_Struct(100/fulllength * postHeaderBytes.Length, postHeaderBytes.Length, fulllength) 
    ' Write out the file contents 
    RaiseEvent TextMessage("Write out the file contents") 
    Dim buffer As Byte() = New [Byte](CUInt(Math.Min(4096, CInt(fileStream.Length))) - 1) {} 
    Dim bytesRead As Integer = 0 
    While (InlineAssignHelper(bytesRead, fileStream.Read(buffer, 0, buffer.Length))) <> 0 
     requestStream.Write(buffer, 0, bytesRead) 
     Progress = New Progress_Struct(100/fulllength * (Progress.bytes_read + buffer.Length), Progress.bytes_read + buffer.Length, fulllength) 
    End While 
    RaiseEvent TextMessage("bytesRead = " + bytesRead.ToString) 
    RaiseEvent TextMessage("postHeaderBytes.length = " + postHeaderBytes.Length.ToString) 
    RaiseEvent TextMessage("Main File bytes written") 
    ' Write out the trailing boundary 
    requestStream.Write(boundaryBytes, 0, boundaryBytes.Length) 
    Progress = New Progress_Struct(100/fulllength * (Progress.bytes_read + boundaryBytes.Length), Progress.bytes_read + boundaryBytes.Length, fulllength) 

    Dim responce As WebResponse 
    Try 
     RaiseEvent TextMessage("Trying normal response...") 
     responce = webrequest__1.GetResponse() 
    Catch ex As Net.WebException 
     RaiseEvent TextMessage("ERROR " + ex.Status.ToString + " Trying to get Error response.") 
     responce = ex.Response 
    End Try 

    Dim s As Stream = responce.GetResponseStream() 
    Dim sr As New StreamReader(s) 

    ContinueProgressLoop = False 
    Dim returnstr As String = sr.ReadToEnd() 
    'SendHtmlMessage(returnstr) 

    RaiseEvent ProgressChange(Progress) 
    RaiseEvent UploadFinished(returnstr) 
    RaiseEvent TextMessage("Working FALSE") 
    working = False 
    Return returnstr 
End Function 

我希望有人能幫助我。我無法弄清楚什麼是錯的。

它應該返回帶有重定向的「上傳成功」消息,但它只返回上傳頁面本身。我用網絡嗅探器進行了檢查。

回答

1

爲什麼不看看System.Net.WebClient班呢? http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx這樣你不必擔心格式化POST數據,你只需撥打WebClient.UploadFile()http://msdn.microsoft.com/en-us/library/36s52zhs.aspx

+0

我試過了。但是我必須傳輸多個帖子值,這意味着我必須傳輸多部分/表單數據。 UploadFile()不支持這一點。 – sinni800 2010-01-08 16:58:04

+0

好的,現在我終於明白了這個問題。還有一件事 - 在讀取responseStream之前,必須在RequestStream()上調用close()。在我的答案在這裏看到一個例子:http://stackoverflow.com/questions/1948552/sharepoint-2007-how-to-check-if-a-folder-exists-in-a-document-library/2005855#2005855 – naivists 2010-01-08 17:30:45

+0

我現在明白了。花了一段時間。在請求的最後,我錯過了一些「 - 」。比較瀏覽器的請求和我的!我通過使用Wireshark來整理它。 – sinni800 2010-05-10 14:29:12

相關問題