HttpWebRequest kullanarak form verilerini gönderme


91

Bazı form verilerini kendi web uygulamamın içinde olmayan belirli bir URL'ye göndermek istiyorum. "Domain.client.nl" gibi aynı etki alanına sahiptir. Web uygulamasında bir "web.domain.client.nl" url'si var ve göndermek istediğim url "idp.domain.client.nl". Ama benim kodum hiçbir şey yapmıyor ..... birisi neyi yanlış yaptığımı biliyor mu?

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


6
Diğerinin özellikle kullanmak istediği gibi, tam olarak bir kopya değil WebClient.

Yanıtlar:


72

Hem alan adı hem de değer URL olarak kodlanmalıdır. gönderi verilerinin ve sorgu dizesinin biçimi aynıdır

.Net yapmanın yolu şuna benzer

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

Bu, alanları ve değer adlarını kodlamayı halleder.


10
string postdata = outgoingQueryString.ToString();size değeri olan bir dizge verecektir "System.Collections.Specialized.NameValueCollection".
sfuqua

1
Aslında @sfuqua, HttpUtility (özellikle System.Web'deki) kaynağını yeniden derlerseniz, bunun özelleştirilmiş bir NameValueCollection türü döndürdüğünü göreceksiniz: return (NameValueCollection) new HttpValueCollection (sorgu, false, true, kodlama); hangi koleksiyonu doğru bir şekilde bir sorgu dizesine dönüştürür. Eğer Ancak RestSharp birini kullanırsanız, ... değil
Senatör

İlginç, tam olarak bu sorunu gördüğüm için ToString(), ancak şimdi RestSharp'ı kullanırken olup olmadığını hatırlayamıyorum. Kesin olasılık. Düzeltme için teşekkürler.
sfuqua

outgoingQueryStringÖrnek kodun ima ettiği gibi nasıl çalıştığı hemen belli değildi . Bu iki soru - (1) HttpValueCollection ve NameValueCollection ve (2) anahtar-değer çiftleri veya benzerleri verilen bir sorgu dizesi oluşturan herhangi bir .NET sınıfıdır .
Kenny Evitt

57

Bunu dene:

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

6
Yazmayı tercih ederim: request.Method = WebRequestMethods.Http.Post;
Totalys

kontrol isteği.Kullanımdan önce yanıt
Marco Fantasia

@MarcoFantasia Eğer kontrol ederseniz request.HaveResponseaslında zorunda olsun ilk tepkisi. HttpWebResponse response = (HttpWebResponse) request.GetResponse(); if (request.HaveResponse) { ... }
Evet Barry

41

Formu yanlış kodluyorsunuz. Yalnızca değerleri kodlamalısınız:

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

Düzenle

Yanılmışım RFC1866 bölüm 8.2.1'e göre hem adlar hem de değerler kodlanmalıdır.

Ancak verilen örnek için, isimlerde kodlanması gereken herhangi bir karakter bulunmadığından bu durumda kod örneğim doğrudur;)

Web sunucusunun kodu çözememesinin nedeni bu olan eşittir işaretini kodlayacağı için sorudaki kod hala yanlıştır.

Daha uygun bir yol olurdu:

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

Teşekkürler, ancak şimdi şu hatayı alıyorum: Uzak sunucu bir hata verdi: (412) Ön Koşul Başarısız.
wsplinter

Çok google'lıyorum :) Ama düzelttim, kirli bir şekilde yapıyorum. Bir HttpWebRequest yapmıyorum, ancak bir String içinde bir html formu oluşturuyorum ve onu tarayıcıya yazıyorum (onload'da bir göndereceğim).
wsplinter

3
@wsplinter: Çözümü ön koşullandırmanın başarısız olduğunu belgelerseniz başkalarına yardımcı olur.
jgauffin

@jgauffin: Radyo düğmesi değerlerini nasıl gönderirim? Aynı gruba ait 3 radyo düğmem olduğunu varsayalım.
Asad Refai

1
Görünüşe göre, UrlEncode @ gibi sembolleri API çağrısında kabul edilmeyen bir koda değiştirdiği için bu benim için tam olarak çalışmadı; @ user3389691'in cevabında gösterilen olarak NameValueCollection kullanmak için değiştirmek mükemmel çalışıyor.
dhruvpatel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.