2010-03-02 17 views
8

Bien, aquí está el trato. Como dice la pregunta, estoy tratando de enviar un archivo a un servidor web y tengo algunos problemas.Usando .NET para publicar un archivo en el servidor HttpWebRequest o WebClient

He intentado publicar este mismo archivo en el mismo servidor web utilizando Curl.exe y no he tenido problemas. Publiqué las banderas que utilicé con curl solo en caso de que pudieran señalar posibles razones por las que estoy teniendo problemas con las clases de .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 

estoy tratando de utilizar una clase .NET como cliente Web o HttpWebRequest para hacer lo mismo. Aquí hay una muestra del código que he probado. Con WebClient obtengo un error de la versión HTTP 505 no admitido y con HttpWebRequest obtengo un 501 no implementado.

Al tratar con un cliente 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); 
} 

Y mientras se utiliza un 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

usar un proxy HTTP de depuración para ver exactamente cuál es la diferencia entre las dos llamadas a través de cable. Pruebe Charles (http://www.charlesproxy.com/) o Fiddler (http://www.fiddler2.com/fiddler2/). –

Respuesta

10

En primer lugar, usar algo como violinista e inspeccionar las solicitudes y respuestas para ver qué se diferencia entre rizo y System.Net.WebClient.

Además, puede intentar (aunque la inspección con el proxy de depuración debe permitir que te permite detectar la diferencia):

utilizar la caché de credenciales para establecer sus credenciales para la autenticación básica:

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

Conjunto una encabezado de agente de usuario:

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

Cambiar la versión del protocolo en la WebRequest:

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

El "Cambiar la versión del protocolo en la WebRequest" hizo el truco! – Myishmael

+0

Problema similar: Agregar un encabezado de agente de usuario lo solucionó por mí. –

1

Puede haber otras 2 razones cuando un acuerdo 501.

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

cuando el POSDATAR contiene algunos Chracter chino o algún otro carácter. p.

postDate = "type=user&username=计算机学院&password=123&Submit=+登录+" 

para publicar el mensaje correcto, también puede agregar la siguiente línea 2;

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

esto también conduce a una

501.

en esa ocasión, se puede eliminar la línea 2, y modificar son posteriores como tal.

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

tal vez esta es una solución para modificar la fecha de publicación, sin embargo no he probado aún.

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

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

si Response.StatusCode == HttpStatusCode.Redirect de redireccionamiento es igual a 302. siguiente línea es una necesidad:

Request.AllowAutoRedirect = false; 
Cuestiones relacionadas