2013-02-05 28 views
70

Tôi muốn đăng một số dữ liệu biểu mẫu tới một URL được chỉ định không nằm trong ứng dụng web của riêng tôi. Nó có cùng tên miền, chẳng hạn như "domain.client.nl". Ứng dụng web có url "web.domain.client.nl" trên url mà tôi muốn đăng là "idp.domain.client.nl". Nhưng mã của tôi không có gì ..... ai đó biết tôi đang làm gì sai?Dữ liệu biểu mẫu bài đăng bằng cách sử dụng HttpWebRequest

Wouter

StringBuilder postData = new StringBuilder(); 
postData.Append(HttpUtility.UrlEncode(String.Format("username={0}&", uname))); 
postData.Append(HttpUtility.UrlEncode(String.Format("password={0}&", pword))); 
postData.Append(HttpUtility.UrlEncode(String.Format("url_success={0}&", urlSuccess))); 
postData.Append(HttpUtility.UrlEncode(String.Format("url_failed={0}", urlFailed))); 

ASCIIEncoding ascii = new ASCIIEncoding(); 
byte[] postBytes = ascii.GetBytes(postData.ToString()); 

// set up request object 
HttpWebRequest request; 
try 
{ 
    request = (HttpWebRequest)HttpWebRequest.Create(WebSiteConstants.UrlIdp); 
} 
catch (UriFormatException) 
{ 
    request = null; 
} 
if (request == null) 
    throw new ApplicationException("Invalid URL: " + WebSiteConstants.UrlIdp); 

request.Method = "POST"; 
request.ContentType = "application/x-www-form-urlencoded"; 
request.ContentLength = postBytes.Length; 
request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"; 

// add post data to request 
Stream postStream = request.GetRequestStream(); 
postStream.Write(postBytes, 0, postBytes.Length); 
postStream.Flush(); 
postStream.Close(); 
+0

có thể trùng lặp: http://stackoverflow.com/questions/5401501/how-to-post-data-to-specific-url-using-webclient-in-c-sharp – Dariusz

+4

Không khá trùng lặp, vì người khác đặc biệt muốn sử dụng 'WebClient'. –

Trả lời

34

Bạn đang mã hóa các hình thức không chính xác. Bạn chỉ nên mã hóa các giá trị:

StringBuilder postData = new StringBuilder(); 
postData.Append("username=" + HttpUtility.UrlEncode(uname) + "&"); 
postData.Append("password=" + HttpUtility.UrlEncode(pword) + "&"); 
postData.Append("url_success=" + HttpUtility.UrlEncode(urlSuccess) + "&"); 
postData.Append("url_failed=" + HttpUtility.UrlEncode(urlFailed)); 

chỉnh sửa

tôi là không chính xác. Theo RFC1866 section 8.2.1 cả tên và giá trị phải được mã hóa.

Nhưng đối với các ví dụ được đưa ra, những cái tên không có bất kỳ nhân vật mà cần phải được mã hóa, vì vậy trong trường hợp này mã ví dụ của tôi là đúng;)

Các mã trong câu hỏi là vẫn không chính xác vì nó sẽ mã hóa dấu bằng là lý do tại sao máy chủ web không thể giải mã nó.

Một cách thích hợp hơn sẽ là:

StringBuilder postData = new StringBuilder(); 
postData.AppendUrlEncoded("username", uname); 
postData.AppendUrlEncoded("password", pword); 
postData.AppendUrlEncoded("url_success", urlSuccess); 
postData.AppendUrlEncoded("url_failed", urlFailed); 

//in an extension class 
public static void AppendUrlEncoded(this StringBuilder sb, string name, string value) 
{ 
    if (sb.Length != 0) 
     sb.Append("&"); 
    sb.Append(HttpUtility.UrlEncode(name)); 
    sb.Append("="); 
    sb.Append(HttpUtility.UrlEncode(value)); 
} 
+0

Cảm ơn, nhưng tôi đã nhận được lỗi sau: Máy chủ từ xa trả về lỗi: (412) Điều kiện tiên quyết Không thành công. – wsplinter

+0

bạn đã google nó chưa? – jgauffin

+0

Tôi google rất nhiều :) Nhưng tôi đã sửa nó, tôi đang làm nó theo cách bẩn thỉu. Tôi không phải là một HttpWebRequest nhưng tôi xây dựng một hình thức html bên trong một String và wirte nó vào trình duyệt (trong onload tôi sẽ làm một trình). – wsplinter

61

Cả hai tên trường và giá trị nên được url mã hóa. định dạng của bài dữ liệu và chuỗi truy vấn đều giống nhau

Cách .net làm là một cái gì đó như thế này

NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty); 
outgoingQueryString.Add("field1","value1"); 
outgoingQueryString.Add("field2", "value2"); 
string postdata = outgoingQueryString.ToString(); 

này sẽ chăm sóc của mã hóa các lĩnh vực và các tên giá trị

+8

'string postdata = outgoingQueryString.ToString();' sẽ cung cấp cho bạn một chuỗi với giá trị '" System.Collections.Specialized.NameValueCollection "'. – sfuqua

+1

Trên thực tế @sfuqua nếu bạn dịch ngược nguồn cho HttpUtility (cụ thể là một trong System.Web) bạn sẽ thấy rằng nó trả về một loại NameValueCollection chuyên biệt: return (NameValueCollection) mới HttpValueCollection (truy vấn, sai, true, encoding); chuyển đổi tập hợp thành chuỗi truy vấn một cách chính xác. Nếu bạn sử dụng một từ RestSharp tuy nhiên, nó không ... –

+0

Thú vị, như tôi đã thấy vấn đề chính xác này với 'ToString()', mặc dù bây giờ tôi không thể nhớ nếu nó đã được trong khi sử dụng RestSharp. Khả năng xác định. Cảm ơn vì sự đúng đắn của bạn. – sfuqua

35

Thử này:

var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/recepticle.aspx"); 

var postData = "thing1=hello"; 
    postData += "&thing2=world"; 
var data = Encoding.ASCII.GetBytes(postData); 

request.Method = "POST"; 
request.ContentType = "application/x-www-form-urlencoded"; 
request.ContentLength = data.Length; 

using (var stream = request.GetRequestStream()) 
{ 
    stream.Write(data, 0, data.Length); 
} 

var response = (HttpWebResponse)request.GetResponse(); 

var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); 
+2

làm việc như sự quyến rũ, cảm ơn :) –

+2

Tôi thà viết: request.Method = WebRequestMethods.Http.Post; – Totalys

+0

kiểm tra yêu cầu.HaveResponse trước khi sử dụng phản hồi –

Các vấn đề liên quan