2013-02-05 21 views
70

Desidero inviare alcuni dati di modulo a un URL specificato che non si trova all'interno della mia applicazione web. Ha lo stesso dominio, ad esempio "domain.client.nl". L'applicazione web ha un url "web.domain.client.nl" nell'url dove voglio postare è "idp.domain.client.nl". Ma il mio codice non fa nulla ..... qualcuno sa cosa sto facendo male?Inserisci dati modulo utilizzando 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

Eventuali duplicati: http://stackoverflow.com/questions/5401501/how-to-post-data-to-specific-url-using-webclient-in-c-sharp Non – Dariusz

+4

piuttosto un duplicato, in quanto l'altro vuole utilizzare in particolare 'WebClient'. –

risposta

34

si codifica la forma in modo non corretto. Si dovrebbe codificare solo i valori:

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

modificare

ero errato. Secondo lo RFC1866 section 8.2.1, sia i nomi che i valori dovrebbero essere codificati.

Ma per l'esempio dato, i nomi non hanno alcun carattere che deve essere codificata, quindi in questo caso il mio esempio di codice è corretto;)

Il codice in questione non è ancora corretta come sarebbe codificare il segno di uguale che è la ragione per cui il web server non può decodificarlo.

Un modo più corretto sarebbe stato:

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

Grazie, ma ho ricevuto il seguente errore: Il server remoto ha restituito un errore: (412) Precondizione non riuscita. – wsplinter

+0

l'hai google? – jgauffin

+0

Ho un sacco di google :) Ma l'ho risolto, lo sto facendo in modo pungente. Non ho una HttpWebRequest, ma costruisco un modulo html all'interno di una stringa e lo collego al browser (nell'onload farò un submit). – wsplinter

61

Sia il nome del campo e il valore deve essere URL codificato. formato dei dati postali e stringa di ricerca sono gli stessi

Il modo .net di fare è qualcosa di simile

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

Questo si prenderà cura di codificare i campi ei nomi dei valori

+8

'string postdata = outgoingQueryString.ToString();' ti darà una stringa con il valore '" System.Collections.Specialized.NameValueCollection "'. – sfuqua

+1

In realtà @sfuqua se decompilate l'origine per HttpUtility (in particolare quella in System.Web) vedrete che restituisce un tipo NameValueCollection specializzato: return (NameValueCollection) new HttpValueCollection (query, false, true, encoding); che converte correttamente la collezione in una stringa di query. Se si utilizza quello di RestSharp, tuttavia, non ... –

+0

Interessante, come ho visto questo esatto problema con 'ToString()', anche se ora non riesco a ricordare se fosse durante l'utilizzo di RestSharp. Possibilità definita. Grazie per la correzione. – sfuqua

35

Try questo:

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

ha funzionato come un incantesimo, grazie :) –

+2

Preferisco scrivere: request.Method = WebRequestMethods.Http.Post; – Totalys

+0

check request.HaveResponse prima della risposta all'utilizzo –

Problemi correlati