[c#] Post form data using HttpWebRequest

I want to post some form data to a specified URL that isn't inside my own web application. It has the same domain, such like "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". 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();

This question is related to c# post httpwebrequest

The answer is


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.

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.

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

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

Both the field name and the value should be url encoded. format of the post data and query string are the same

The .net way of doing is something like this

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


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to post

How to post query parameters with Axios? How can I add raw data body to an axios request? HTTP POST with Json on Body - Flutter/Dart How do I POST XML data to a webservice with Postman? How to set header and options in axios? Redirecting to a page after submitting form in HTML How to post raw body data with curl? How do I make a https post in Node Js without any third party module? How to convert an object to JSON correctly in Angular 2 with TypeScript Postman: How to make multiple requests at the same time

Examples related to httpwebrequest

C# HttpWebRequest The underlying connection was closed: An unexpected error occurred on a send How to properly make a http web GET request Send JSON via POST in C# and Receive the JSON returned? How to create JSON post to api using C# Use C# HttpWebRequest to send json to web service Post form data using HttpWebRequest HttpWebRequest-The remote server returned an error: (400) Bad Request Get host domain from URL? How to ignore the certificate check when ssl Receiving JSON data back from HTTP request