CG.Infrastructure.Http 3.10.7

dotnet add package CG.Infrastructure.Http --version 3.10.7
                    
NuGet\Install-Package CG.Infrastructure.Http -Version 3.10.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CG.Infrastructure.Http" Version="3.10.7" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CG.Infrastructure.Http" Version="3.10.7" />
                    
Directory.Packages.props
<PackageReference Include="CG.Infrastructure.Http" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CG.Infrastructure.Http --version 3.10.7
                    
#r "nuget: CG.Infrastructure.Http, 3.10.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CG.Infrastructure.Http@3.10.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CG.Infrastructure.Http&version=3.10.7
                    
Install as a Cake Addin
#tool nuget:?package=CG.Infrastructure.Http&version=3.10.7
                    
Install as a Cake Tool

CG.Infrastructure.Http

A comprehensive HTTP client library for .NET applications that provides robust HTTP operations, authentication support, proxy configuration, and response handling with multiple client types and security features.

Features

  • HTTP Operations: Full CRUD operations (GET, POST, PUT, DELETE) with generic entity support
  • Authentication Support: OAuth 2.0 client credentials and password grant flows
  • Multiple Client Types: Basic, token-based, custom handler, and authenticated HTTP clients
  • Custom Headers: Configurable custom HTTP headers with environment variable support
  • Proxy Configuration: Configurable proxy settings for enterprise environments
  • Response Handling: Multiple response formats (string, string array, generic entities)
  • Discovery Document Support: OpenID Connect discovery document retrieval
  • User Info Support: OAuth 2.0 user information retrieval
  • Testing Utilities: API endpoint testing and link validation
  • Network Utilities: Host ping functionality and connection testing
  • Dependency Injection Ready: Easy integration with ASP.NET Core applications

Installation

dotnet add package CG.Infrastructure.Http

Quick Start

1. Register Services

using Infrastructure.Http.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Register HTTP services
builder.Services.RegisterInfraHttpServices(builder.Configuration);

2. Inject and Use

public class MyController : ControllerBase
{
    private readonly IHttpService _httpService;

    public MyController(IHttpService httpService)
    {
        _httpService = httpService;
    }

    public async Task<IActionResult> GetData()
    {
        var response = await _httpService.Get("api/data");
        var data = await _httpService.GetResponseAsEntity<MyData>(response);
        return Ok(data);
    }
}

3. Add Configuration

{
  "ProxyOptions": {
    "UseProxy": false,
    "ProxyHost": "proxy.company.com",
    "ProxyPort": 8080
  },
  "IssuerOptions": {
    "Authority": "https://identity.example.com",
    "Audience": "my-api"
  },
  "CustomHeaders": {
    "Headers": {
      "x-gg-bot-access": "{{ENV:GG_BOT_ACCESS_TOKEN}}",
      "Accept": "application/json"
    }
  }
}

Core Services

IHttpService

Comprehensive HTTP service interface with authentication and response handling:

public interface IHttpService : IService
{
    // HTTP Operations
    Task<HttpResponseMessage?> Get(string? requestUri, TokenResponse? token = null, string? baseUrl = null, HttpClientEnum client = HttpClientEnum.Basic);
    Task<HttpResponseMessage?> Post<TEntity>(string? requestUri, TEntity? data, TokenResponse? token = null, string? baseUrl = null, HttpClientEnum client = HttpClientEnum.Basic);
    Task<HttpResponseMessage?> Put<TEntity>(string? requestUri, TEntity? data, TokenResponse? token = null, string? baseUrl = null, HttpClientEnum client = HttpClientEnum.Basic);
    Task<HttpResponseMessage?> Delete(string? requestUri, Guid? id, TokenResponse? token = null, string? baseUrl = null, HttpClientEnum client = HttpClientEnum.Basic);

    // Response Handling
    Task<string> GetResponseAsString(HttpResponseMessage response);
    Task<string[]> GetResponseAsStringArray(HttpResponseMessage response);
    Task<TEntity?> GetResponseAsEntity<TEntity>(HttpResponseMessage response);

    // Authentication
    Task<DiscoveryDocumentResponse?> GetDiscoveryDocument(string? requestUri, HttpClientEnum client = HttpClientEnum.Basic);
    Task<TokenResponse?> RequestClientToken(string? requestUri, ClientCredentialsTokenRequest request, HttpClientEnum client = HttpClientEnum.Basic);
    Task<TokenResponse?> RequestPasswordToken(string? requestUri, PasswordTokenRequest request, HttpClientEnum client = HttpClientEnum.Basic);
    Task<UserInfoResponse?> GetUserInfo(string? requestUri, UserInfoRequest request, HttpClientEnum client = HttpClientEnum.Basic);

    // Testing and Utilities
    Task<bool> Test(string? requestUri, string? format = null, HttpClientEnum client = HttpClientEnum.Basic);
    Task TestWithToken(TokenResponse? token, string? requestUri, string? format = null, HttpClientEnum client = HttpClientEnum.Basic);
    Task TestApiClientLinks(List<TestLink>? testLinks);
    bool PingHost(string? nameOrAddress);
}

HTTP Operations

Basic HTTP Requests

// GET request
var response = await _httpService.Get("api/users");

// POST request with entity
var user = new User { Name = "John", Email = "john@example.com" };
var response = await _httpService.Post("api/users", user);

// PUT request with entity
var updatedUser = new User { Id = 1, Name = "John Updated", Email = "john.updated@example.com" };
var response = await _httpService.Put("api/users/1", updatedUser);

// DELETE request
var response = await _httpService.Delete("api/users", Guid.Parse("12345678-1234-1234-1234-123456789012"));

Custom Header Requests

// GET request with custom headers (authenticated client)
var response = await _httpService.Get("api/protected", client: HttpClientEnum.Authenticated);

// POST request with custom headers
var response = await _httpService.Post("api/secure", data, client: HttpClientEnum.Authenticated);

// All HTTP methods support custom headers via HttpClientEnum.Authenticated

Response Handling

// Get response as string
var response = await _httpService.Get("api/data");
var content = await _httpService.GetResponseAsString(response);

// Get response as string array
var response = await _httpService.Get("api/items");
var items = await _httpService.GetResponseAsStringArray(response);

// Get response as typed entity
var response = await _httpService.Get("api/users");
var users = await _httpService.GetResponseAsEntity<List<User>>(response);

Authentication

OAuth 2.0 Client Credentials Flow

// Create client credentials request
var request = _httpService.GetClientCredentialsToken(
    "https://identity.example.com/connect/token",
    "client-id",
    "client-secret",
    "api-scope"
);

// Request token
var token = await _httpService.RequestClientToken(
    "https://identity.example.com/connect/token",
    request
);

// Use token for authenticated requests
var response = await _httpService.Get("api/protected", token);

OAuth 2.0 Password Grant Flow

// Create password token request
var securePassword = new SecureString();
foreach (char c in "password123") securePassword.AppendChar(c);

var request = _httpService.GetClientPasswordToken(
    "https://identity.example.com/connect/token",
    "client-id",
    "client-secret",
    "api-scope",
    "username",
    securePassword
);

// Request token
var token = await _httpService.RequestPasswordToken(
    "https://identity.example.com/connect/token",
    request
);

User Information

// Get user info request
var userInfoRequest = _httpService.GetUserInfoRequest(
    "https://identity.example.com/connect/userinfo",
    token
);

// Retrieve user information
var userInfo = await _httpService.GetUserInfo(
    "https://identity.example.com/connect/userinfo",
    userInfoRequest
);

Discovery Document

// Get OpenID Connect discovery document
var discovery = await _httpService.GetDiscoveryDocument(
    "https://identity.example.com"
);

if (discovery != null)
{
    var tokenEndpoint = discovery.TokenEndpoint;
    var userInfoEndpoint = discovery.UserInfoEndpoint;
}

Client Types

HttpClientEnum

public enum HttpClientEnum
{
    Basic = 1,          // Standard HTTP client
    Token = 2,          // Token-based authentication client
    Handler = 3,        // Custom message handler client
    Authenticated = 4   // Client with custom headers (e.g., API keys, custom Accept)
}

Client Usage Examples

// Basic client (default)
var response = await _httpService.Get("api/data", client: HttpClientEnum.Basic);

// Token-based client
var response = await _httpService.Get("api/protected", token, client: HttpClientEnum.Token);

// Custom handler client
var response = await _httpService.Get("api/data", client: HttpClientEnum.Handler);

// Authenticated client with custom headers
var response = await _httpService.Get("api/secure", client: HttpClientEnum.Authenticated);

Custom Header Behavior

When using HttpClientEnum.Authenticated:

  • Custom headers are applied first from the configuration
  • Default headers are applied as fallback if no custom headers are configured
  • Custom headers override defaults (e.g., custom Accept header takes precedence)
  • Environment variables are resolved at runtime for sensitive values
  • Fallback to default behavior if custom headers are not configured

Configuration Options

ProxyOptions

public class ProxyOptions
{
    public string? Url { get; set; }                    // Proxy URL
    public bool UseProxy { get; set; } = false;         // Enable/disable proxy
    public string? ProxyHost { get; set; }              // Proxy hostname
    public int ProxyPort { get; set; }                  // Proxy port number
}

CustomHeaderOptions

public class CustomHeaderOptions
{
    public Dictionary<string, string> Headers { get; set; } = new();
}

Configuration Example

{
  "ProxyOptions": {
    "UseProxy": true,
    "ProxyHost": "proxy.company.com",
    "ProxyPort": 8080
  },
  "CustomHeaders": {
    "Headers": {
      "x-api-key": "{{ENV:API_KEY}}",
      "x-gg-bot-access": "{{ENV:GG_BOT_ACCESS_TOKEN}}",
      "Accept": "application/json",
      "User-Agent": "MyApp/1.0"
    }
  }
}

Environment Variable Support

Custom headers support environment variable substitution using the {{ENV:VARIABLE_NAME}} syntax:

# Set environment variables
export API_KEY="your-api-key-here"
export GG_BOT_ACCESS_TOKEN="your-bot-token-here"

# Or in Windows PowerShell
$env:API_KEY="your-api-key-here"
$env:GG_BOT_ACCESS_TOKEN="your-bot-token-here"

Advanced Usage

Custom HTTP Message Handler

public class CustomHttpMessageHandler : HttpMessageHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken)
    {
        // Custom logic before request
        request.Headers.Add("X-Custom-Header", "CustomValue");
        
        // Send request
        var response = await base.SendAsync(request, cancellationToken);
        
        // Custom logic after response
        return response;
    }
}

// Use custom handler
var handler = new CustomHttpMessageHandler();
var httpService = new HttpService(logger, proxyOptions, issuerOptions, 
    serializationService, substringService, secureStringService, handler);

Base URL Configuration

// Use base URL for all requests
var response = await _httpService.Get("users", baseUrl: "https://api.example.com");
// Results in: https://api.example.com/users

// Combine base URL with specific endpoint
var response = await _httpService.Post("users", user, baseUrl: "https://api.example.com");
// Results in: https://api.example.com/users

Testing Utilities

// Test endpoint availability
var isAvailable = await _httpService.Test("https://api.example.com/health");

// Test with specific format
var isAvailable = await _httpService.Test("https://api.example.com/health", "json");

// Test with authentication token
await _httpService.TestWithToken(token, "https://api.example.com/protected");

// Test multiple API client links
var testLinks = new List<TestLink>
{
    new TestLink
    {
        TokenEndpoint = "https://identity.example.com/connect/token",
        ClientId = "client-id",
        ClientSecret = "client-secret",
        ClientScope = "api-scope",
        Links = new Dictionary<string, string?>
        {
            { "Users", "https://api.example.com/users" },
            { "Orders", "https://api.example.com/orders" }
        }
    }
};

await _httpService.TestApiClientLinks(testLinks);

Network Utilities

// Ping host to check connectivity
var isReachable = _httpService.PingHost("api.example.com");
var isReachable = _httpService.PingHost("192.168.1.1");

Service Registration

Automatic Registration

public static class ServiceCollectionExtensions
{
    public static IServiceCollection RegisterInfraHttpServices(
        this IServiceCollection services, 
        IConfiguration configuration)
    {
        services.RegisterProxyOptions(configuration);
        services.RegisterCustomHeaderOptions(configuration);
        
        // Register HttpClient as singleton with default headers
        services.AddHttpClient<HttpService>(client =>
        {
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
        });

        return services;
    }
}

Manual Registration

services.AddSingleton<ProxyOptions>(provider =>
{
    var configuration = provider.GetRequiredService<IConfiguration>();
    var proxyOptions = new ProxyOptions();
    
    configuration.GetSection("ProxyOptions").Bind(proxyOptions);
    
    return proxyOptions;
});

services.AddHttpClient<HttpService>();
services.AddScoped<IHttpService, HttpService>();

Error Handling

Response Validation

var response = await _httpService.Get("api/data");

if (response != null && response.IsSuccessStatusCode)
{
    var data = await _httpService.GetResponseAsEntity<MyData>(response);
    return Ok(data);
}
else
{
    var errorContent = response != null 
        ? await _httpService.GetResponseAsString(response)
        : "No response received";
    
    return BadRequest($"Request failed: {errorContent}");
}

Exception Handling

try
{
    var response = await _httpService.Get("api/data");
    var data = await _httpService.GetResponseAsEntity<MyData>(response);
    return Ok(data);
}
catch (HttpRequestException ex)
{
    logger.LogError(ex, "HTTP request failed");
    return StatusCode(500, "External service unavailable");
}
catch (Exception ex)
{
    logger.LogError(ex, "Unexpected error");
    return StatusCode(500, "Internal server error");
}

Best Practices

  1. Client Management: Use appropriate client types for different scenarios
  2. Token Handling: Store and reuse tokens when possible to reduce authentication calls
  3. Error Handling: Always check response status and handle errors gracefully
  4. Configuration: Use strongly-typed configuration options for proxy and issuer settings
  5. Logging: Leverage built-in logging for debugging and monitoring
  6. Security: Use secure string handling for sensitive data like passwords
  7. Testing: Use built-in testing utilities to validate API endpoints
  8. Base URLs: Configure base URLs for consistent endpoint management
  9. Custom Headers: Use environment variables for sensitive header values
  10. Header Security: Never hardcode API keys or tokens in configuration files

Dependencies

  • CG.Infrastructure.Configuration (3.10.1) - Configuration management
  • CG.Infrastructure.Services (3.10.2) - Shared service implementations
  • IdentityModel (7.0.0) - OAuth 2.0 and OpenID Connect support
  • Microsoft.Extensions.Http (9.0.8) - HTTP client factory

Performance Considerations

  • Connection Pooling: HTTP clients are managed efficiently with connection pooling
  • Token Caching: Implement token caching to reduce authentication overhead
  • Response Streaming: Use streaming for large response payloads
  • Timeout Configuration: Set appropriate timeouts for different operations
  • Proxy Optimization: Configure proxy settings for optimal network performance

Security Features

  • Secure String Handling: Secure string support for sensitive data
  • Token-based Authentication: OAuth 2.0 token management
  • Proxy Support: Enterprise proxy configuration
  • HTTPS Enforcement: Built-in support for secure connections
  • Header Management: Custom header support for security requirements

Troubleshooting

Common Issues

  1. Proxy Configuration: Verify proxy settings match your network environment
  2. Authentication Failures: Check client credentials and scopes
  3. Timeout Issues: Adjust timeout settings for slow networks
  4. SSL/TLS Errors: Ensure proper certificate validation
  5. Response Parsing: Verify response format matches expected entity types
  6. Custom Header Issues: Check environment variable names and values
  7. Header Override Problems: Verify custom headers are properly configured

Debug Mode

Enable detailed logging for troubleshooting:

// In appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Infrastructure.Http": "Debug"
    }
  }
}

Version History

  • 3.10.4: Current release with comprehensive HTTP operations
  • 3.10.3: Enhanced authentication and testing features
  • 3.10.2: Improved proxy and client type support
  • 3.10.1: Initial HTTP service framework
  • 3.10.0: Foundation release

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

For support and questions:

  • Create an issue in the repository
  • Check the documentation
  • Review the test examples

CG.Infrastructure.Http - Robust HTTP operations for modern .NET applications.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on CG.Infrastructure.Http:

Package Downloads
CG.Infrastructure.Responses

Infra Responses library with shared services

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.10.7 18 8/16/2025
3.10.6 59 8/15/2025
3.10.5 88 8/10/2025
3.10.4 158 7/2/2025
3.10.3 146 6/17/2025
3.10.2 147 6/16/2025
3.10.1 291 6/11/2025
3.10.0 308 6/11/2025
3.9.0 130 12/10/2024
3.0.2 171 8/13/2024
3.0.1 153 8/12/2024
3.0.0 152 3/26/2024
2.0.1 297 6/2/2023
2.0.0 187 6/2/2023
1.0.2 509 6/17/2022
1.0.1 438 6/17/2022
1.0.0 506 5/27/2022