Table of contents

What is the purpose of the HttpRequestMessage class in HttpClient (C#)?

The HttpRequestMessage class is a fundamental component of the HttpClient API that encapsulates all the information needed to send an HTTP request. Part of the System.Net.Http namespace, this class provides fine-grained control over HTTP requests, making it ideal for advanced scenarios where you need more flexibility than the simplified HttpClient methods offer.

Purpose and Core Functionality

The HttpRequestMessage class serves as a complete representation of an HTTP request, including:

  • HTTP method (GET, POST, PUT, DELETE, etc.)
  • Request URI
  • HTTP headers
  • Request content/body
  • HTTP version and other configuration options

Key Properties and Capabilities

1. HTTP Method Control

Set the HTTP method using the Method property:

var request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/users");
// Or using custom methods
request.Method = new HttpMethod("PATCH");

2. Request URI Management

Configure the target URI with the RequestUri property:

request.RequestUri = new Uri("https://api.example.com/users/123");

3. Header Customization

Add custom headers through the Headers property:

request.Headers.Add("Authorization", "Bearer your-token-here");
request.Headers.Add("User-Agent", "MyApp/1.0");
request.Headers.Add("X-Custom-Header", "custom-value");

4. Content Handling

Set request body content using the Content property:

var jsonContent = new StringContent(
    JsonSerializer.Serialize(userData),
    Encoding.UTF8,
    "application/json"
);
request.Content = jsonContent;

Practical Examples

Basic GET Request with Custom Headers

using System;
using System.Net.Http;
using System.Threading.Tasks;

public class ApiClient
{
    private readonly HttpClient _httpClient;

    public ApiClient()
    {
        _httpClient = new HttpClient();
    }

    public async Task<string> GetDataAsync()
    {
        var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/data");

        // Add custom headers
        request.Headers.Add("Accept", "application/json");
        request.Headers.Add("Authorization", "Bearer your-token");
        request.Headers.Add("User-Agent", "MyApp/1.0");

        try
        {
            var response = await _httpClient.SendAsync(request);
            response.EnsureSuccessStatusCode();

            return await response.Content.ReadAsStringAsync();
        }
        catch (HttpRequestException ex)
        {
            Console.WriteLine($"Request failed: {ex.Message}");
            throw;
        }
    }
}

POST Request with JSON Content

public async Task<HttpResponseMessage> CreateUserAsync(User user)
{
    var request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/users");

    // Set JSON content
    var json = JsonSerializer.Serialize(user);
    request.Content = new StringContent(json, Encoding.UTF8, "application/json");

    // Add headers
    request.Headers.Add("Accept", "application/json");
    request.Headers.Add("Authorization", "Bearer your-token");

    return await _httpClient.SendAsync(request);
}

Advanced Configuration with Timeout and Cancellation

public async Task<string> GetWithTimeoutAsync(CancellationToken cancellationToken = default)
{
    var request = new HttpRequestMessage(HttpMethod.Get, "https://api.example.com/slow-endpoint");

    // Configure request options
    request.Headers.Add("Accept", "application/json");
    request.Version = HttpVersion.Version20; // Use HTTP/2

    // Add custom properties for logging or tracking
    request.Options.Set(new HttpRequestOptionsKey<string>("RequestId"), Guid.NewGuid().ToString());

    try
    {
        using var response = await _httpClient.SendAsync(request, cancellationToken);
        response.EnsureSuccessStatusCode();

        return await response.Content.ReadAsStringAsync(cancellationToken);
    }
    catch (OperationCanceledException)
    {
        Console.WriteLine("Request was cancelled");
        throw;
    }
}

Multipart Form Data Example

public async Task<HttpResponseMessage> UploadFileAsync(string filePath, Dictionary<string, string> formData)
{
    var request = new HttpRequestMessage(HttpMethod.Post, "https://api.example.com/upload");

    using var multipartContent = new MultipartFormDataContent();

    // Add form fields
    foreach (var kvp in formData)
    {
        multipartContent.Add(new StringContent(kvp.Value), kvp.Key);
    }

    // Add file
    var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));
    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
    multipartContent.Add(fileContent, "file", Path.GetFileName(filePath));

    request.Content = multipartContent;
    request.Headers.Add("Authorization", "Bearer your-token");

    return await _httpClient.SendAsync(request);
}

When to Use HttpRequestMessage

Use HttpRequestMessage when you need:

  • Custom Headers: Adding authorization tokens, API keys, or custom headers
  • Complex Content: Sending multipart data, custom content types, or binary data
  • HTTP Method Flexibility: Using methods beyond GET/POST or custom HTTP methods
  • Request Metadata: Adding properties for logging, tracking, or middleware processing
  • Fine-grained Control: Specifying HTTP version, timeout behavior, or other advanced options

For simple scenarios, the convenience methods like GetAsync(), PostAsync(), and PutAsync() are perfectly adequate. However, when you need the full power and flexibility of HTTP request configuration, HttpRequestMessage is the appropriate choice.

Best Practices

  1. Reuse HttpClient: Create one HttpClient instance and reuse it for multiple requests
  2. Dispose Properly: Use using statements or implement IDisposable patterns
  3. Handle Exceptions: Always wrap HTTP calls in try-catch blocks
  4. Use Cancellation Tokens: Support request cancellation for better resource management
  5. Configure Timeouts: Set appropriate timeouts for your use case

The HttpRequestMessage class provides the foundation for building robust, configurable HTTP clients in C# applications, offering the flexibility needed for complex API integrations and web scraping scenarios.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon