2009-11-01 14 views
9

Vì vậy, tôi đang cố gắng đăng một thứ gì đó lên máy chủ web.C# HttpWebRequest POST'ing thất bại

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

Trông ổn, tôi đang thiết lập nội dung có độ dài dựa trên kích thước của dữ liệu được mã hóa ... Dù sao nó không thành công tại sw.flush() với "byte được ghi vào dòng vượt quá nội dung -Kích thước bước sóng được chỉ định "

Trình phát trực tuyến có thực hiện một số phép thuật sau lưng tôi mà tôi không biết? Có cách nào tôi có thể nhìn vào những gì StreamWriter đang làm?

Trả lời

24

Các câu trả lời khác đã giải thích cách tránh điều này, nhưng tôi nghĩ tôi sẽ trả lời vì sao nó xảy ra: bạn sẽ kết thúc bằng byte order mark trước nội dung thực tế của mình.

Bạn có thể tránh điều này bằng cách gọi new UTF8Encoding(false) thay vì sử dụng Encoding.UTF8. Đây là một chương trình ngắn để chứng minh sự khác biệt:

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

Điểm tốt. Tôi nghĩ * về việc đào, nhưng ...

+0

Bạn thưa ông :) Giải thích rằng quan sát về \ 357 \ 273 \ 277 từ wireshark i được đưa ra trong nhận xét khác. Rất cám ơn! –

4

Có lẽ làm như dễ dàng hơn:

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

Hoặc xem here cho một cuộc thảo luận cho phép sử dụng như:

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

Bạn không cần phải thiết lập ContentLength một cách rõ ràng, vì nó sẽ được đặt tự động với kích thước của dữ liệu được viết để yêu cầu luồng khi bạn đóng.

+0

Bạn thực sự là chính xác; điều này khắc phục sự cố cụ thể đó. Nhưng khi sử dụng Wireshark để xem gói được gửi cho thấy StreamWriter đang chuẩn bị sẵn thứ gì đó cho dữ liệu POST ... \ 357 \ 273 \ 277id = 301Rbu 3 byte đó đến từ đâu ??? Content-Length được đặt thành 12 trong gói này. –

+2

@Jon Skeet mô tả rõ điều này (như thường lệ =)) - cái này được gọi là 'dấu ngoặc đơn byte Unicode' xác định văn bản là UTF-8, UTF-16 Big-endian, UTF-16 Little-endian, v.v. Đọc thêm tại đây http://en.wikipedia.org/wiki/Byte-order_mark –