2009-09-24 17 views
15

He visto tantas implementaciones de envío de publicaciones HTTP, y es cierto que no entiendo completamente los detalles subyacentes para saber qué se necesita.Canonical HTTP POST code?

¿Cuál es el código sucinto/correcto/canónico para enviar un HTTP POST en C# .NET 3.5?

Quiero un método genérico como

public string SendPost(string url, string data) 

que se puede agregar a una biblioteca y usa siempre para publicar los datos y devolverá la respuesta del servidor.

Respuesta

10

creo que la versión simple de esto sería

var client = new WebClient(); 
return client.UploadString(url, data); 

La clase System.Net.WebClient tiene otros métodos útiles que le permiten descargar o cargar un archivo o cadenas, o bytes.

Lamentablemente, hay (con bastante frecuencia) situaciones en las que debe hacer más trabajo. Lo anterior, por ejemplo, no se ocupa de las situaciones en las que necesita autenticarse contra un servidor proxy (aunque usará la configuración de proxy predeterminada para IE).

También el cliente Web no admite la carga de múltiples archivos o configuración (algunos específicos) encabezados y, a veces tendrá que ir más profundo y utilizar el

System.Web.HttpWebRequest y System.Net.HttpWebResponse lugar.

+0

+1 para WebClient.UploadString! con respecto a las limitaciones de WebClient, hay una solución fácil, vea mi respuesta –

+0

Una cosa común que me encuentro haciendo es publicar xml en un servicio web. ¿UploadString es una buena opción para este escenario? ¿Qué hay de la codificación? ¿es UTF-16? – User

+0

puede configurar la codificación en UFT-16 utilizando la propiedad Codificación del WebClient. –

0

Compare:

// create a client object 
using(System.Net.WebClient client = new System.Net.WebClient()) { 
    // performs an HTTP POST 
    client.UploadString(url, xml); 

} 

a

string HttpPost (string uri, string parameters) 
{ 
    // parameters: name1=value1&name2=value2 
    WebRequest webRequest = WebRequest.Create (uri); 
    webRequest.ContentType = "application/x-www-form-urlencoded"; 
    webRequest.Method = "POST"; 
    byte[] bytes = Encoding.ASCII.GetBytes (parameters); 
    Stream os = null; 
    try 
    { // send the Post 
     webRequest.ContentLength = bytes.Length; //Count bytes to send 
     os = webRequest.GetRequestStream(); 
     os.Write (bytes, 0, bytes.Length);   //Send it 
    } 
    catch (WebException ex) 
    { 
     MessageBox.Show (ex.Message, "HttpPost: Request error", 
     MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
    finally 
    { 
     if (os != null) 
     { 
     os.Close(); 
     } 
    } 

    try 
    { // get the response 
     WebResponse webResponse = webRequest.GetResponse(); 
     if (webResponse == null) 
     { return null; } 
     StreamReader sr = new StreamReader (webResponse.GetResponseStream()); 
     return sr.ReadToEnd().Trim(); 
    } 
    catch (WebException ex) 
    { 
     MessageBox.Show (ex.Message, "HttpPost: Response error", 
     MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
    return null; 
} // end HttpPost 

Por qué las personas utilizan/escritura de este último?

+3

Normalmente, porque tenemos que modificar la solicitud más allá de lo que permite la clase de WebClient, en particular si desea cambiar ciertos encabezados WebClient restringe la capacidad de hacerlo, consulte http://msdn.microsoft.com/ en-us/library/system.net.webclient.headers.aspx – RobV

3

Como han dicho otros, WebClient.UploadString (o UploadData) es el camino a seguir.

Sin embargo, el WebClient incorporado tiene un inconveniente importante: casi no tiene control sobre el WebRequest que se utiliza detrás de la escena (cookies, autenticación, encabezados personalizados ...). Una forma simple de resolver ese problema es crear su WebClient personalizado y anular el método GetWebRequest. A continuación, puede personalizar la solicitud antes de que se envíe (puede hacer lo mismo para la respuesta sobrescribiendo GetWebResponse). Aquí está an example de un cookie-aware WebClient. Es tan simple que me hace preguntarme por qué el WebClient incorporado no lo maneja de fábrica ...

+0

genial, gracias por el enlace! –