'Moving from HttpWebRequest to HttpClient

I would like to update some legacy code from using HttpWebRequest to use HttpClient, but I am not quite sure how to send string to the REST API I am accessing.

Legacy code:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "text/xml";
request.ContentLength = payload.Length;
if (credentials != null)
{
     request.Credentials = credentials;
}

// Send the request
Stream requestStream = request.GetRequestStream();
requestStream.Write(payload, 0, payload.Length);
requestStream.Close();

// Get the response
response = (HttpWebResponse)request.GetResponse();

Can I use the HttpClient.GetStreamAsync method and use the stream like we did with the web request? Or is there a way to use SendAsync with content and then get the response?



Solution 1:[1]

using var handler = new HttpClientHandler { Credentials = ... };
using var client = new HttpClient(handler);

var content = new StringContent(payload, Encoding.UTF8, "text/xml");
var response = await client.PostAsync(uri, content);

I've assumed that payload is a string.

Solution 2:[2]

You do not need to access the request stream, you could just directly send the payload, but if there is a reason behind that then this is also possible.

//Do not instantiate httpclient like that, use dependency injection instead
var httpClient = new HttpClient();
var httpRequest = new HttpRequestMessage();

//Set the request method (e.g. GET, POST, DELETE ..etc.)
httpRequest.Method = HttpMethod.Post;
//Set the headers of the request
httpRequest.Headers.Add("Content-Type", "text/xml");

//A memory stream which is a temporary buffer that holds the payload of the request
using (var memoryStream = new MemoryStream())
{
    //Write to the memory stream
    memoryStream.Write(payload, 0, payload.Length);

    //A stream content that represent the actual request stream
    using (var stream = new StreamContent(memoryStream))
    {
        httpRequest.Content = stream;

        //Send the request
        var response = await httpClient.SendAsync(httpRequest);


        //Ensure we got success response from the server
        response.EnsureSuccessStatusCode();
        //you can access the response like that
        //response.Content
    }
}

About the credentials, you need to know what kind of credentials are these? Is it basic auth?

If it's basic auth then you could (while setting the request URI in the HttpRequestMessage object, you could construct the credentials there as well.

var requestUri = new UriBuilder(yourEndPoint)
                        {
                            UserName = UsernameInCredentials,
                            Password = PasswordInCredentials,
                        }
                        .Uri;

And then you just set that as request URI. Read more about why we shouldn't instantiate HttpClient like this here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Csala
Solution 2 Mahmoud