2010-03-02 59 views
8

好的,這是交易。正如問題所述,我試圖將文件發佈到網絡服務器,並且遇到了一些問題。使用.NET將文件發佈到服務器HttpWebRequest或WebClient

我試過把這個文件發佈到使用Curl.exe的同一個web服務器上,並且沒有問題。我已經發布了使用curl的標誌,因爲它們可能會指出我爲什麼在.NET類中遇到問題的任何潛在原因。

curl.exe --user "myUser:myPass" --header "Content-Type: application/gzip" 
--data-binary "@filename.txt.gz" --cookie "data=service; data-ver=2; date=20100212; 
time=0900; location=1234" --output "out.txt" --dump-header "header.txt" 
http://mysite/receive 

我試圖使用.NET類像WebClient或HttpWebRequest做同樣的事情。這是我試過的代碼的一個例子。使用WebClient,我得到一個505 HTTP版本不支持的錯誤,並且使用HttpWebRequest,我得到了501未實現。

當使用Web客戶端嘗試它:

public void sendFileClient(string path){ 
    string url = "http://mysite/receive"; 
    WebClient wc = new WebClient(); 
    string USERNAME = "myUser"; 
    string PSSWD = "myPass"; 

    NetworkCredential creds = new NetworkCredential(USERNAME, PSSWD); 
    wc.Credentials = creds; 
    wc.Headers.Set(HttpRequestHeader.ContentType, "application/gzip"); 
    wc.Headers.Set("Cookie", "location=1234; date=20100226; time=1630; data=service; data-ver=2"); 

    wc.UploadFile(url, "POST", path); 
} 

雖然使用的HttpRequest:

public Stream sendFile(string path) 
{ 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create("http://myserver/receive"); 
    string USERNAME = "myUser";  
    string PSSWD = "myPass"; 
    NetworkCredential creds = new NetworkCredential(USERNAME, PSSWD); 
    request.Credentials = creds; 
    request.Method = "POST"; 
    request.ContentType = "application/gzip";  
    request.Headers.Set("Cookie", "location=1234; date=20100226; time=1630; data=service; data-ver=2"); 
    FileInfo fInfo = new FileInfo(path); 
    long numBytes = fInfo.Length; 
    FileStream fStream = new FileStream(path, FileMode.Open, FileAccess.Read); 
    BinaryReader br = new BinaryReader(fStream); 
    byte[] data = br.ReadBytes((int)numBytes); 
    br.Close(); 
    fStream.Close(); 
    fStream.Dispose(); 
    Stream wrStream = request.GetRequestStream(); 
    BinaryWriter bw = new BinaryWriter(wrStream); 
    bw.Write(data); 
    bw.Close(); 
    HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
    return response.GetResponseStream(); 
} 
+1

使用調試http代理看出差別正是在導線上的兩個電話之間。試試Charles(http://www.charlesproxy.com/)或Fiddler(http://www.fiddler2.com/fiddler2/)。 – 2010-03-02 04:27:36

回答

10

首先,使用這樣的小提琴手和檢查請求和響應,看嫋嫋之間有什麼不同和System.Net.WebClient。

此外,您還可以嘗試(雖然與調試代理檢查應該讓你精確定位的差異):

憑據緩存設置您的憑據基本身份驗證:

var cc= new CredentialCache(); 
cc.Add(new Uri(url), 
        "Basic", 
        new NetworkCredential("USERNAME", "PASSWORD")); 
wc.Credentials = cc; 

設置一個用戶代理報頭:

string _UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; 
wc.Headers.Add(HttpRequestHeader.UserAgent, _UserAgent); 

變化問題的WebRequest的協議版本:

reqeust.KeepAlive = false; 
request.ProtocolVersion=HttpVersion.Version10; 
+0

「更改WebRequest上的協議版本」訣竅! – Myishmael 2010-03-02 13:28:27

+0

類似問題:添加一個用戶代理標題爲我修復了它。 – 2011-06-29 15:09:29

1

501協議可能還有另外兩個原因。

---------- --------- 1

當踵包含一些中國Chracter或其它字符。 例如

postDate = "type=user&username=計算機學院&password=123&Submit=+登錄+" 

爲了發佈正確的消息,您還可以添加以下2行;

Request.SendChunked = true; 
Request.TransferEncoding = "GB2312"; 

這也導致在該場合501

,你可以刪除2線,並修改踵像這樣。

postDate = "type=user&username=%BC%C6%CB%E3%BB%FA%D1%A7%D4%BA&password=123&Submit=+%C8%B7%C8%CF+" 

也許這是一個解決方案來修改postDate,但我還沒有測試。

string str = Encoding.GetEncoding("gb2312").GetString(tmpBytes); 

---------- --------- 2

如果Response.StatusCode == HttpStatusCode.Redirect重定向是等於302。 下面一行是必須的:

Request.AllowAutoRedirect = false; 
相關問題