diff --git a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient.csproj b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient.csproj
index 0bb3be0f0d..21f31fb431 100644
--- a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient.csproj
+++ b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient.csproj
@@ -2,14 +2,14 @@
Exe
- net8.0
+ net10.0
enable
enable
-
-
+
+
diff --git a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/Program.cs b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/Program.cs
index 0d5c2d1f34..67e0623b53 100644
--- a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/Program.cs
+++ b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/HowToSetDefaultUserAgentOnHttpClient/Program.cs
@@ -9,37 +9,60 @@ public static void Main(string[] args)
{
var host = BuildHost();
- var httpClientFactory = host.Services.GetService();
+ var httpClientFactory = host.Services.GetRequiredService();
GetDefaultAgentOnHttpClient(httpClientFactory);
+ SetUserAgentOnHttpRequestMessage("CodeMazeDesktopApp/1.1");
+
SetUserAgentOnHttpRequestMessage("CodeMazeDesktopApp", "1.1");
}
public static IHost BuildHost()
{
- var builder = new HostBuilder()
- .ConfigureServices(services =>
- {
- services.AddHttpClient("CodeMazeHttpClient", client =>
- {
- var productHeaderValue = new ProductHeaderValue(name: "CodeMazeDesktopApp", version: "1.1");
- var productInfoHeaderValue = new ProductInfoHeaderValue(productHeaderValue);
+ var builder = Host.CreateApplicationBuilder();
+
+ builder.Services.AddHttpClient("CodeMazeHttpClient", client =>
+ {
+ var productHeaderValue = new ProductHeaderValue(name: "CodeMazeDesktopApp", version: "1.1");
+ var productInfoHeaderValue = new ProductInfoHeaderValue(productHeaderValue);
+
+ client.DefaultRequestHeaders.UserAgent.Add(productInfoHeaderValue);
+ });
+
+ return builder.Build();
+ }
+
+ public static IHost BuildHostWithUserAgentForAllClients()
+ {
+ var builder = Host.CreateApplicationBuilder();
- client.DefaultRequestHeaders.UserAgent.Add(productInfoHeaderValue);
- });
+ builder.Services.ConfigureHttpClientDefaults(httpClientBuilder =>
+ {
+ httpClientBuilder.ConfigureHttpClient(client =>
+ {
+ client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("CodeMazeDesktopApp", "1.1"));
});
+ });
return builder.Build();
}
public static string GetDefaultAgentOnHttpClient(IHttpClientFactory httpClientFactory)
- {
+ {
var httpClient = httpClientFactory.CreateClient("CodeMazeHttpClient");
return httpClient.DefaultRequestHeaders.UserAgent.ToString();
}
+ public static string SetUserAgentOnHttpRequestMessage(string userAgentValue)
+ {
+ var httpRequestMessage = new HttpRequestMessage();
+ httpRequestMessage.Headers.Add("User-Agent", userAgentValue);
+
+ return httpRequestMessage.Headers.UserAgent.ToString();
+ }
+
public static string SetUserAgentOnHttpRequestMessage(string productName, string productVersion)
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "/users/1234");
@@ -51,4 +74,4 @@ public static string SetUserAgentOnHttpRequestMessage(string productName, string
return httpRequestMessage.Headers.UserAgent.ToString();
}
-}
\ No newline at end of file
+}
diff --git a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/ProgramUnitTests.cs b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/ProgramUnitTests.cs
index 7170558ada..6ce359bfbd 100644
--- a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/ProgramUnitTests.cs
+++ b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/ProgramUnitTests.cs
@@ -5,6 +5,19 @@ namespace Tests;
public class ProgramUnitTests
{
+ [Fact]
+ public void WhenUserAgentStringIsProvided_ThenSetUserAgentOnHttpRequestMessageSetsTheHeader()
+ {
+ //Arrange
+ var userAgentValue = "CodeMazeDesktopApp/1.1";
+
+ //Act
+ var actualOutput = Program.SetUserAgentOnHttpRequestMessage(userAgentValue);
+
+ //Assert
+ Assert.Equal(userAgentValue, actualOutput);
+ }
+
[Fact]
public void WhenUserAgentPropertyIsProvided_ThenSetUserAgentOnHttpRequestMessageSetsTheHeader()
{
@@ -30,11 +43,29 @@ public void WhenHttpClientIsRegisteredWithHostBuilder_ThenHttpClientGetsDefaultU
//Act
var host = Program.BuildHost();
- var httpClientFactory = host.Services.GetService();
+ var httpClientFactory = host.Services.GetRequiredService();
var actualOutput = Program.GetDefaultAgentOnHttpClient(httpClientFactory);
//Assert
Assert.Equal(expectedOutput, actualOutput);
}
-}
\ No newline at end of file
+
+ [Fact]
+ public void WhenClientDefaultsAreConfigured_ThenEveryClientGetsDefaultUserAgent()
+ {
+ //Arrange
+ var expectedOutput = "CodeMazeDesktopApp/1.1";
+
+ //Act
+ var host = Program.BuildHostWithUserAgentForAllClients();
+ var httpClientFactory = host.Services.GetRequiredService();
+
+ var namedClient = httpClientFactory.CreateClient("AnyName");
+ var defaultClient = httpClientFactory.CreateClient();
+
+ //Assert
+ Assert.Equal(expectedOutput, namedClient.DefaultRequestHeaders.UserAgent.ToString());
+ Assert.Equal(expectedOutput, defaultClient.DefaultRequestHeaders.UserAgent.ToString());
+ }
+}
diff --git a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/Tests.csproj b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/Tests.csproj
index 179687640e..5117625127 100644
--- a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/Tests.csproj
+++ b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net10.0
enable
enable
@@ -10,16 +10,20 @@
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/UserAgentOnTheWireTests.cs b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/UserAgentOnTheWireTests.cs
new file mode 100644
index 0000000000..c5539b93a1
--- /dev/null
+++ b/aspnetcore-features/HowToSetDefaultUserAgentOnHttpClient/Tests/UserAgentOnTheWireTests.cs
@@ -0,0 +1,64 @@
+using HowToSetDefaultUserAgentOnHttpClient;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using System.Net.Http.Headers;
+
+namespace Tests;
+
+public class UserAgentOnTheWireTests : IAsyncLifetime
+{
+ private WebApplication _app = null!;
+ private string _baseAddress = null!;
+
+ public async Task InitializeAsync()
+ {
+ var builder = WebApplication.CreateBuilder();
+ builder.WebHost.UseUrls("http://127.0.0.1:0");
+
+ _app = builder.Build();
+ _app.MapGet("/user-agent", (HttpRequest request) => request.Headers.UserAgent.ToString());
+
+ await _app.StartAsync();
+ _baseAddress = _app.Urls.First();
+ }
+
+ public async Task DisposeAsync() => await _app.DisposeAsync();
+
+ [Fact]
+ public async Task WhenPlainHttpClientCallsTheServer_ThenNoUserAgentArrives()
+ {
+ using var httpClient = new HttpClient();
+
+ var userAgent = await httpClient.GetStringAsync($"{_baseAddress}/user-agent");
+
+ Assert.Equal(string.Empty, userAgent);
+ }
+
+ [Fact]
+ public async Task WhenNamedClientCallsTheServer_ThenServerReadsTheDefaultUserAgent()
+ {
+ var httpClientFactory = Program.BuildHost().Services.GetRequiredService();
+ var httpClient = httpClientFactory.CreateClient("CodeMazeHttpClient");
+
+ var userAgent = await httpClient.GetStringAsync($"{_baseAddress}/user-agent");
+
+ Assert.Equal("CodeMazeDesktopApp/1.1", userAgent);
+ }
+
+ [Fact]
+ public async Task WhenRequestSetsItsOwnUserAgent_ThenItReplacesTheDefault()
+ {
+ var httpClientFactory = Program.BuildHost().Services.GetRequiredService();
+ var httpClient = httpClientFactory.CreateClient("CodeMazeHttpClient");
+
+ var request = new HttpRequestMessage(HttpMethod.Get, $"{_baseAddress}/user-agent");
+ request.Headers.UserAgent.Add(new ProductInfoHeaderValue("CodeMazeReportJob", "2.0"));
+
+ var response = await httpClient.SendAsync(request);
+ var userAgent = await response.Content.ReadAsStringAsync();
+
+ Assert.Equal("CodeMazeReportJob/2.0", userAgent);
+ }
+}