简体   繁体   English

使用 HttpWebRequest 发布表单数据

[英]Post form data using HttpWebRequest

I want to post some form data to a specified URL that isn't inside my own web application.我想将一些表单数据发布到不在我自己的 web 应用程序中的指定 URL 中。 It has the same domain, such like "domain.client.nl".它具有相同的域,例如“domain.client.nl”。 The web application has a url "web.domain.client.nl" en the url where I want to post to is "idp.domain.client.nl". web 应用程序有一个 url "web.domain.client.nl" 和 url 我要发布到的地方是 "idp.nl"client. But my code does nothing..... does someone knows what I'm doing wrong?但是我的代码什么也没做......有人知道我做错了什么吗?

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

Both the field name and the value should be url encoded.字段名和值都应该是 url 编码的。 format of the post data and query string are the same帖子数据和查询字符串的格式相同

The .net way of doing is something like this .net 的做法是这样的

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

This will take care of encoding the fields and the value names这将负责对字段和值名称进行编码

Try this:试试这个:

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

You are encoding the form incorrectly.您对表单的编码不正确。 You should only encode the values:您应该只对值进行编码:

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

edit编辑

I was incorrect.我错了。 According to RFC1866 section 8.2.1 both names and values should be encoded.根据RFC1866 第 8.2.1 节,名称和值都应该被编码。

But for the given example, the names do not have any characters that needs to be encoded, so in this case my code example is correct ;)但是对于给定的示例,名称没有任何需要编码的字符,因此在这种情况下,我的代码示例是正确的;)

The code in the question is still incorrect as it would encode the equal sign which is the reason to why the web server cannot decode it.问题中的代码仍然不正确,因为它会对等号进行编码,这就是 Web 服务器无法对其进行解码的原因。

A more proper way would have been:更合适的方法是:

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

Use this code:使用此代码:

internal void SomeFunction() {
    Dictionary<string, string> formField = new Dictionary<string, string>();
    
    formField.Add("Name", "Henry");
    formField.Add("Age", "21");
    
    string body = GetBodyStringFromDictionary(formField);
    // output : Name=Henry&Age=21
}

internal string GetBodyStringFromDictionary(Dictionary<string, string> formField)
{
    string body = string.Empty;
    foreach (var pair in formField)
    {
        body += $"{pair.Key}={pair.Value}&";   
    }

    // delete last "&"
    body = body.Substring(0, body.Length - 1);

    return body;
}
List<KeyValuePair<string, string>> formField= new List<KeyValuePair<string,string>>();

formField.Add(new KeyValuePair<string, string>("Name", "Henry"));
formField.Add(new KeyValuePair<string, string>("Age", "21"));

var body = string.Join("&", formField.Select(kvp => $"{kvp.Key}={kvp.Value}"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM