2009-11-01 23 views
9

Estoy intentando enviar algo a un servidor web.C# HttpWebRequest POST'ing falla

System.Net.HttpWebRequest EventReq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("url"); 
System.String Content = "id=" + Id; 
EventReq.ContentLength = System.Text.Encoding.UTF8.GetByteCount(Content); 
EventReq.Method = "POST"; 
EventReq.ContentType = "application/x-www-form-urlencoded"; 
System.IO.StreamWriter sw = new System.IO.StreamWriter(EventReq.GetRequestStream(), System.Text.Encoding.UTF8); 
sw.Write(Content); 
sw.Flush(); 
sw.Close(); 

ve bien, Soy la creación de longitud de contenido basado en el tamaño de los datos codificados ... De todos modos falla en sw.flush() con "bytes que se escriben en la corriente exceda el contenido -Longitud de tamaño especificado "

¿No estoy al tanto de StreamWriter haciendo magia detrás de mi espalda? ¿Hay alguna manera de ver lo que StreamWriter está haciendo?

Respuesta

24

Otras respuestas han explicado cómo evitar esto, pero pensé que respondería por qué está sucediendo: terminará con un byte order mark antes de su contenido real.

Puede evitar esto llamando al new UTF8Encoding(false) en lugar de usar Encoding.UTF8. Aquí hay un programa corto para demostrar la diferencia:

using System; 
using System.Text; 
using System.IO; 

class Test  
{ 
    static void Main() 
    { 
     Encoding enc = new UTF8Encoding(false); // Prints 1 1 
     // Encoding enc = Encoding.UTF8; // Prints 1 4 
     string content = "x"; 
     Console.WriteLine(enc.GetByteCount("x")); 
     MemoryStream ms = new MemoryStream(); 
     StreamWriter sw = new StreamWriter(ms, enc); 
     sw.Write(content); 
     sw.Flush(); 
     Console.WriteLine(ms.Length); 
    } 

} 
+0

Buen lugar. Yo * pensé * sobre excavar, pero ...

+0

Usted señor tiene razón :) Explica esa observación sobre \ 357 \ 273 \ 277 de wireshark que hice en el otro comentario. ¡Muchas gracias! –

4

tal vez hacer como más fácil:

using(WebClient client = new WebClient()) { 
    NameValueCollection values = new NameValueCollection(); 
    values.Add("id",Id); 
    byte[] resp = client.UploadValues("url","POST", values); 
} 

O ver here para una discusión que permite su uso como:

client.Post(destUri, new { 
    id = Id // other values here 
}); 
3

No es necesario configurar ContentLength de forma explícita, ya que se ajusta automáticamente al tamaño de Datos escritos para solicitar transmisión cuando la cierra.

+0

Usted es de hecho correcto; esto soluciona ese problema en particular. Pero el uso de Wireshark para observar el paquete que se envía muestra que StreamWriter está anteponiendo algo a los datos POST ... \ 357 \ 273 \ 277id = 301Rbu ¿De dónde vienen esos 3 bytes? Content-Length se establece en 12 en este paquete. –

+2

@Jon Skeet describió esto bien (como siempre =)) - esto es llamado 'marca de orden byte Unicode' que identifica si el texto es UTF-8, UTF-16 Big-endian, UTF-16 Little-endian etc. Lea más aquí http://en.wikipedia.org/wiki/Byte-order_mark –

Cuestiones relacionadas