Using HttpRequestConfig with HttpClient and HttpWebRequest

I’ve been reading the documentation on http-utils.

The doc says:

Which lets you configure a HttpRequestConfig that is equally applied to their HttpClient and HttpWebRequest implementations.

I think I’m going about this the wrong way.

using this HttpRequestConfig:

    HttpRequestConfig cfg = new ();
    cfg.AddHeader(HttpHeaders.Accept, MimeTypes.Json);
    cfg.SetAuthBearer("theapikey");
    cfg.ContentType = MimeTypes.Json;

How can the above HttpRequestConfig be applied/used to/with HttpClient and HttpWebRequest?

Could you provide a simple example of each…? Or explain how this class is intended to be used?

I’ve looked but I can’t find one.

Thanks.

Here is an simple console program example with HttpClient doing a GET request.

using ServiceStack;

using var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://web.web-templates.io/hello/world");

httpRequestMessage.With(config =>
{
    config.Accept = "application/json";
    config.UserAgent = "MyCustomAgent/1.0";
});

var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
        
Console.WriteLine($"Response: {responseBody}");

Another performing a post:

using System.Text;
using ServiceStack;
using ServiceStack.Text;

using var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "https://web.web-templates.io/hello");

var payload = new { Name = "world" };
var payloadString = JsonSerializer.SerializeToString(payload);

httpRequestMessage.Content = new StringContent(payloadString, Encoding.UTF8);

httpRequestMessage.With(config =>
{
    config.ContentType = "application/json";
    config.Accept = "application/json";
});

var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
        
Console.WriteLine($"Response: {responseBody}");

If you aren’t using HttpClient, the same can be used to configure HttpWebRequest:

HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create("https://web.web-templates.io/hello/world");

httpWebRequest.With(config =>
{
    config.Accept = "application/json";
    config.UserAgent = "MyCustomAgent/1.0";
});

HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

using (StreamReader reader = new StreamReader(httpWebResponse.GetResponseStream()))
{
    string response = reader.ReadToEnd();
    Console.WriteLine($"Response: {response}");
}

So you can use your cfg in the With action to configure the options.

The https-utils page shows examples used with other extension methods like GetJsonFromUrlAsync where the requestFilter action is supplying the HttpWebRequest or HttpRequestMessage in with the interchangeable .With actions are used:

var json = await url.GetJsonFromUrlAsync(requestFilter: req => 
    req.With(c => {
        c.UserAgent = UserAgent;
        c.SetAuthBasic(ClientId, ClientSecret);
    }), token: token).ConfigAwait();

So the same type of request code can be reduced quite a bit to this simplified form for common use cases where your requestFilter action code might be common.

Hope that helps.

I’m really missing something here… Thank you for the multiple examples.

Your first example is what I’m looking for. How would you use the pre-populated HttpRequestConfig ? I mean how can you pass in cfg ?

Let’s say In your example:

using ServiceStack;

HttpRequestConfig cfg = new ();
cfg.AddHeader(HttpHeaders.Accept, MimeTypes.Json);
cfg.SetAuthBearer("theapikey");
cfg.ContentType = MimeTypes.Json;

using var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "https://web.web-templates.io/hello/world");

httpRequestMessage.With(config =>
{
    config = cfg; // ? 
});

var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
var responseBody = await httpResponseMessage.Content.ReadAsStringAsync();
    
Console.WriteLine($"Response: {responseBody}");

HttpRequestConfig is what to use to configure the existing pre-configured http request, not reassign it.

You can pass a local function to With() it instead:

void Config(HttpRequestConfig cfg) {
    cfg.AddHeader(HttpHeaders.Accept, MimeTypes.Json);
    cfg.SetAuthBearer("theapikey");
    cfg.ContentType = MimeTypes.Json;
}

httpRequestMessage.With(Config);
1 Like