7

I am trying to make a program that requests my website with a username, password, hardware ID and a key in POST.

I have this code here that should send a POST request to my website with that form data, but when it sends, my webserver reports back that it didn't receive the POST data

try
{
    string poststring = String.Format("username={0}&password={1}&key={2}&hwid={3}", Username, Password, "272453745345934756392485764589", GetHardwareID());
    HttpWebRequest httpRequest =
(HttpWebRequest)WebRequest.Create("mywebsite");

    httpRequest.Method = "POST";
    httpRequest.ContentType = "application/x-www-form-urlencoded";

    byte[] bytedata = Encoding.UTF8.GetBytes(poststring);
    httpRequest.ContentLength = bytedata.Length;

    Stream requestStream = httpRequest.GetRequestStream();
    requestStream.Write(bytedata, 0, bytedata.Length);
    requestStream.Close();


    HttpWebResponse httpWebResponse =
    (HttpWebResponse)httpRequest.GetResponse();
    Stream responseStream = httpWebResponse.GetResponseStream();

    StringBuilder sb = new StringBuilder();

    using (StreamReader reader =
    new StreamReader(responseStream, System.Text.Encoding.UTF8))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            sb.Append(line);
        }
    }

    return sb.ToString();
}
catch (Exception Error)
{
    return Error.ToString();
}

If someone could help me, I would really appreciate it.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • 1
    Does this answer your question? [Post form data using HttpWebRequest](https://stackoverflow.com/questions/14702902/post-form-data-using-httpwebrequest) – Amirhossein Mehrvarzi Jul 01 '20 at 16:51

1 Answers1

11

As per HttpWebRequest documentation

We don't recommend that you use HttpWebRequest for new development. Instead, use the System.Net.Http.HttpClient class.

HttpClient contains only asynchronous API because Web requests needs awaiting. That's not good to freeze entire Application while it's pending response.

Thus, here's some async function to make POST request with HttpClient and send there some data.

First of all, create HttpClient seperately because

HttpClient is intended to be instantiated once per application, rather than per-use.

private static readonly HttpClient client = new HttpClient();

Then implement the method.

private async Task<string> PostHTTPRequestAsync(string url, Dictionary<string, string> data)
{
    using (HttpContent formContent = new FormUrlEncodedContent(data))
    {
        using (HttpResponseMessage response = await client.PostAsync(url, formContent).ConfigureAwait(false))
        {
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
    }
}

Or C# 8.0

private async Task<string> PostHTTPRequestAsync(string url, Dictionary<string, string> data)
{
    using HttpContent formContent = new FormUrlEncodedContent(data);
    using HttpResponseMessage response = await client.PostAsync(url, formContent).ConfigureAwait(false);
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}

Looks easier than your code, right?

Caller async method will look like

private async Task MyMethodAsync()
{
    Dictionary<string, string> postData = new Dictionary<string, string>();
    postData.Add("message", "Hello World!");
    try
    {
        string result = await PostHTTPRequestAsync("http://example.org", postData);
        Console.WriteLine(result);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

If you're not familiar with async/await, it's time to say Hello.

aepot
  • 4,558
  • 2
  • 12
  • 24
  • Long-lived HttpClients bring their own problems, and [there is now a recommended mechanism of instantiating HttpClients that mitigates those too](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests) – Tom W Jul 01 '20 at 16:49
  • @TomW but it's another long and interesting story. For educational purpose and small apps single instance of `HttpClient` is pretty good solution. – aepot Jul 01 '20 at 17:00