2009-11-01 4 views
9

Donc, je suis en train de POST quelque chose à un serveur web.C# HttpWebRequest POST'ing échouant

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(); 

Attend bien, je suis mise en longueur du contenu en fonction de la taille des données encodées ... Quoi qu'il en soit, il échoue à sw.flush() avec « octets à écrire dans le flux dépasser le contenu -Longueur de la longueur spécifiée "

Est-ce que StreamWriter fait de la magie derrière mon dos, je ne suis pas au courant? Existe-t-il un moyen de vérifier ce que fait StreamWriter?

Répondre

24

D'autres réponses ont expliqué comment éviter cela, mais j'ai pensé que je répondrais pourquoi cela se produit: vous vous retrouverez avec un byte order mark avant votre contenu actuel.

Vous pouvez éviter cela en appelant new UTF8Encoding(false) au lieu d'utiliser Encoding.UTF8. Voici un programme court pour démontrer la différence:

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

Bon endroit. J'ai * pensé * à creuser, mais ...

+0

Vous monsieur sont corrects :) Explique que l'observation sur \ 357 \ 273 \ 277 de wireshark j'ai fait dans l'autre commentaire. Merci beaucoup! –

4

Peut-être faire comme plus facile:

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

Ou voir here pour une discussion qui permet d'utiliser comme:

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

Vous devez pas définir ContentLength explicitement, car il sera mis automatiquement à la taille données écrites pour demander le flux lorsque vous le fermez.

+0

Vous avez en effet raison; Cela résout ce problème particulier. Mais en utilisant Wireshark pour regarder le paquet qui est envoyé montre que StreamWriter est un préfixe quelque chose aux données POST ... \ 357 \ 273 \ 277id = 301Rbu D'où viennent ces 3 octets ??? Content-Length est défini sur 12 dans ce paquet. –

+2

@Jon Skeet l'a bien décrit (comme d'habitude =)) - c'est ce que l'on appelle un 'Unicode byte-order mark' qui identifie si le texte est UTF-8, UTF-16 Big-endian, UTF-16 Little-endian etc. Lire la suite ici http://en.wikipedia.org/wiki/Byte-order_mark –