2009-11-01 8 views
9

So versuche ich etwas an einen Webserver zu senden.C# HttpWebRequest POST'ing fehlgeschlagen

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

Sieht in Ordnung, ich bin Einstellung Inhalt Länge basierend auf der Größe der codierten Daten ... Auf jeden Fall scheitert es bei sw.flush() mit „Bytes in den Stream geschrieben werden, überschreiten den Inhalt -Länge Größe angegeben "

Ist StreamWriter etwas Magie hinter meinem Rücken, die mir nicht bewusst ist? Gibt es eine Möglichkeit, in was StreamWriter tut?

Antwort

24

Andere Antworten haben erklärt, wie man das vermeidet, aber ich dachte, ich würde antworten, warum es passiert: Sie enden mit einem byte order mark vor Ihrem eigentlichen Inhalt.

Sie können dies vermeiden, indem Sie new UTF8Encoding(false) anstatt Encoding.UTF8 aufrufen. Hier ist ein kurzes Programm, um den Unterschied zu demonstrieren:

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

Guter Ort. Ich * dachte * über Graben, aber ...

+0

Sie sind richtig :) Erklärt diese Beobachtung über \ 357 \ 273 \ 277 von Wireshark ich in dem anderen Kommentar gemacht. Vielen Dank! –

4

Vielleicht wie einfacher machen:

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

Oder here für eine Diskussion siehe ermöglicht den Einsatz wie:

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

Sie müssen nicht ContentLength explizit festgelegt, da sie automatisch auf die Größe eingestellt werden Daten, die beim Schließen an den Stream gesendet werden.

+0

Sie sind in der Tat richtig; Dies behebt dieses spezielle Problem. Aber die Verwendung von Wireshark, um das Paket zu sehen, das gesendet wird, zeigt, dass StreamWriter etwas den POST-Daten voraussetzt ... \ 357 \ 273 \ 277id = 301Rbu Woher kommen diese 3 Bytes ??? Content-Length ist in diesem Paket auf 12 eingestellt. –

+2

@ Jon Skeet beschrieben dies gut (wie üblich =)) - dies ist so genannte "Unicode-Byte-Order-Marke", die angibt, ob Text UTF-8, UTF-16 Big-Endian, UTF-16 Little-Endian usw. Lesen Sie mehr hier http://en.wikipedia.org/wiki/Byte-order_mark –