diff --git a/HttpClientStudy.Config/ConfigFiles/Config.json b/HttpClientStudy.Config/ConfigFiles/Config.json new file mode 100644 index 0000000..5744e5b --- /dev/null +++ b/HttpClientStudy.Config/ConfigFiles/Config.json @@ -0,0 +1,5 @@ +{ + "WebApi": { + "BaseUrl": "http://localhost:5189" + } +} \ No newline at end of file diff --git a/HttpClientStudy.Config/HttpClientStudy.Config.csproj b/HttpClientStudy.Config/HttpClientStudy.Config.csproj new file mode 100644 index 0000000..d2b277e --- /dev/null +++ b/HttpClientStudy.Config/HttpClientStudy.Config.csproj @@ -0,0 +1,35 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/HttpClientStudy.Config/WebApiConfigExtensions.cs b/HttpClientStudy.Config/WebApiConfigExtensions.cs new file mode 100644 index 0000000..904f076 --- /dev/null +++ b/HttpClientStudy.Config/WebApiConfigExtensions.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration.EnvironmentVariables; +using Microsoft.Extensions.Configuration.CommandLine; +using Microsoft.Extensions.Configuration.Memory; +using Microsoft.Extensions.Configuration.Xml; +using Microsoft.Extensions.Configuration.Ini; +using Microsoft.Extensions.Configuration.Binder; +using Microsoft.Extensions.Configuration.KeyPerFile; +using Microsoft.Extensions.Configuration.Json; +using Microsoft.Extensions.Configuration.UserSecrets; + +using Microsoft.Extensions.Options; + +using NetEscapades.Configuration.Yaml; +using Microsoft.Extensions.DependencyInjection; + +namespace HttpClientStudy.Config +{ + public static class WebApiConfigExtensions + { + /// + /// 添加WebApi配置文件 + /// + public static IConfigurationBuilder AddWebApiConfigration(this IConfigurationBuilder configuration) + { + configuration.AddJsonFile($"ConfigFiles/Config.json", optional: false, reloadOnChange: true); + configuration.AddJsonFile($"ConfigFiles/Config.{System.Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true); + + return configuration; + } + + /// + /// 使用选项模式 + /// + /// + /// + public static IServiceCollection AddWebApiOptions(this IServiceCollection services) + { + var configuration = services.BuildServiceProvider().GetService(); + + + + + services.Configure(configuration); + + services.AddOptions(); + return services; + } + } +} diff --git a/HttpClientStudy.Config/WebApiOption.cs b/HttpClientStudy.Config/WebApiOption.cs new file mode 100644 index 0000000..ec95aa9 --- /dev/null +++ b/HttpClientStudy.Config/WebApiOption.cs @@ -0,0 +1,7 @@ +namespace HttpClientStudy.Config +{ + public class WebApiOption + { + public string BaseUrl { get; set; } + } +} diff --git a/HttpClientStudy.Core/GlobalUsings.cs b/HttpClientStudy.Core/GlobalUsings.cs new file mode 100644 index 0000000..6a3bf72 --- /dev/null +++ b/HttpClientStudy.Core/GlobalUsings.cs @@ -0,0 +1,18 @@ +global using System; +global using System.Linq; +global using System.Text; +global using System.Threading.Tasks; +global using System.Collections.Generic; + +global using System.Net; +global using System.Net.Mime; +global using System.Net.Http; +global using System.Net.Http.Json; +global using System.Net.Http.Headers; + +global using HttpClientStudy.Model; + +global using HttpClientStudy.Core; +global using HttpClientStudy.Core.UseJson; +global using HttpClientStudy.Core.HttpRequests; +global using HttpClientStudy.Core.HttpResponses; \ No newline at end of file diff --git a/HttpClientStudy.Core/HttpClientStudy.Core.csproj b/HttpClientStudy.Core/HttpClientStudy.Core.csproj index d8e431a..e0f30b1 100644 --- a/HttpClientStudy.Core/HttpClientStudy.Core.csproj +++ b/HttpClientStudy.Core/HttpClientStudy.Core.csproj @@ -15,6 +15,7 @@ + diff --git a/HttpClientStudy.Core/HttpError.cs b/HttpClientStudy.Core/HttpError.cs index f9dc187..1393149 100644 --- a/HttpClientStudy.Core/HttpError.cs +++ b/HttpClientStudy.Core/HttpError.cs @@ -1,15 +1,33 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HttpClientStudy.Core +namespace HttpClientStudy.Core { /// /// Http 错误处理 /// public class HttpError { + // 定义一个 HttpClient 实例,共享 + public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) }) + { + BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl) + }; + + public async Task UrlNotFoundAsync() + { + var response = await HttpClient.GetAsync("http://www.notingxxxxxxxx.com/404.html"); + + response.EnsureSuccessStatusCode(); + + return response.StatusCode; + } + + public async Task Http404Async() + { + var response = await HttpClient.GetAsync("http://www.baidu.com/404.html"); + + response.EnsureSuccessStatusCode(); + + return response.StatusCode; + } + } } diff --git a/HttpClientStudy.Core/HttpProxy.cs b/HttpClientStudy.Core/HttpProxy.cs index 1f2d817..e4745b0 100644 --- a/HttpClientStudy.Core/HttpProxy.cs +++ b/HttpClientStudy.Core/HttpProxy.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HttpClientStudy.Core +namespace HttpClientStudy.Core { /// /// Http 代理 diff --git a/HttpClientStudy.Core/WebApiConfig.cs b/HttpClientStudy.Core/WebApiConfig.cs new file mode 100644 index 0000000..b6c1808 --- /dev/null +++ b/HttpClientStudy.Core/WebApiConfig.cs @@ -0,0 +1,7 @@ +namespace HttpClientStudy.Core +{ + public class WebApiConfig + { + public const string WebApiBaseUrl = "http://localhost:5189"; + } +} diff --git a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs new file mode 100644 index 0000000..4b3b01a --- /dev/null +++ b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using HttpClientStudy.Config; + + +using Microsoft.Extensions.Options; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace HttpClientStudy.UnitTest.ConfigTest +{ + public class WebApiConfigTest + { + [Fact] + public void Test() + { + ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddWebApiConfigration(); + + IConfiguration configuration = configurationBuilder.Build(); + + var o = new WebApiOption(); + configuration.GetSection("WebApi").Bind(o); + + var services = new ServiceCollection(); + services.AddSingleton(configuration); + services.AddWebApiOptions(); + + var provider = services.BuildServiceProvider(); + var webApiOptions = provider.GetService>(); + + var webApiUrl = webApiOptions.Value; + + } + } +} diff --git a/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs b/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs index 10fe306..35ad031 100644 --- a/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs @@ -20,7 +20,7 @@ namespace HttpClientStudy.UnitTest.HttpClients /// public static HttpClient GetHttpClient = new HttpClient() { - BaseAddress = new Uri(TestConfig.WebApiBaseUrl), + BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl), }; /// diff --git a/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs b/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs index 673aabe..07ff344 100644 --- a/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs @@ -53,7 +53,7 @@ namespace HttpClientStudy.UnitTest.HttpClients { HttpClient httpClient = new HttpClient(); - var responseMessage = await httpClient.GetAsync(TestConfig.WebApiBaseUrl + "/api/health"); + var responseMessage = await httpClient.GetAsync(WebApiConfig.WebApiBaseUrl + "/api/health"); responseMessage.EnsureSuccessStatusCode(); } @@ -64,7 +64,7 @@ namespace HttpClientStudy.UnitTest.HttpClients { HttpClient httpClient = new HttpClient() { - BaseAddress = new Uri(TestConfig.WebApiBaseUrl) + BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl) }; for (int i = 0; i < 100; i++) { diff --git a/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs index fd45187..2da25ec 100644 --- a/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs @@ -31,7 +31,7 @@ namespace HttpClientStudy.UnitTest.HttpClients //构造中传入管道对象 HttpClient httpClient = new HttpClient(handler); - var sd = await httpClient.GetAsync(TestConfig.WebApiBaseUrl + "/api/health"); + var sd = await httpClient.GetAsync(WebApiConfig.WebApiBaseUrl + "/api/health"); var contentText = await sd.Content.ReadAsStringAsync(); _logger.WriteLine(contentText); @@ -42,7 +42,7 @@ namespace HttpClientStudy.UnitTest.HttpClients { HttpClient client = new PipelineHttpClient().CreateHttpClient(); - var r = await client.GetAsync(TestConfig.WebApiBaseUrl + "/api/health"); + var r = await client.GetAsync(WebApiConfig.WebApiBaseUrl + "/api/health"); r.EnsureSuccessStatusCode(); } } diff --git a/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs index afbdb11..3ede1e5 100644 --- a/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs @@ -16,7 +16,7 @@ { SimpleHttpClient client = new SimpleHttpClient(); - var result = client.Get(TestConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); + var result = client.Get(WebApiConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); Assert.NotNull(result); Assert.NotEmpty(result); @@ -27,7 +27,7 @@ { SimpleHttpClient client = new SimpleHttpClient(); - var result = client.GetJson>(TestConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); + var result = client.GetJson>(WebApiConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); Assert.NotNull(result); Assert.IsAssignableFrom(result); diff --git a/HttpClientStudy.UnitTest/HttpErrorTest.cs b/HttpClientStudy.UnitTest/HttpErrorTest.cs new file mode 100644 index 0000000..3311e7b --- /dev/null +++ b/HttpClientStudy.UnitTest/HttpErrorTest.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HttpClientStudy.UnitTest +{ + public class HttpErrorTest : IDisposable + { + private readonly ITestOutputHelper _logger; + private readonly HttpError _httpError = new HttpError(); + + public HttpErrorTest(ITestOutputHelper outputHelper) + { + _logger = outputHelper; + } + + [Fact] + public async void Test() + { + var code = await _httpError.Http404Async(); + + Assert.Equal(HttpStatusCode.NotFound, code); + } + + public void Dispose() + { + + } + } +} diff --git a/HttpClientStudy.UnitTest/WebApp/BaseResultTest.cs b/HttpClientStudy.UnitTest/WebApp/BaseResultTest.cs index 539a01d..1aa022a 100644 --- a/HttpClientStudy.UnitTest/WebApp/BaseResultTest.cs +++ b/HttpClientStudy.UnitTest/WebApp/BaseResultTest.cs @@ -131,7 +131,6 @@ Assert.Equal(0, result2.Code); Assert.Equal("错误", result2.Message); - var result3 = BaseResultUtil.Error(new { Name = "匿名类" }, 0, "错误"); Assert.NotNull(result3); Assert.IsType(result3.Data!.GetType(), result3.Data); @@ -180,8 +179,7 @@ Assert.Equal(0, result2.Data); Assert.Equal(0, result2.Code); Assert.Contains("异常", result2.Message); - - + var result3 = BaseResultUtil.Exception(new Exception("测试异常"),new { Name = "匿名类" }, 0); Assert.NotNull(result3); Assert.IsType(result3.Data!.GetType(), result3.Data); diff --git a/HttpClientStudy.UnitTest/WebApp/TestConfig.cs b/HttpClientStudy.UnitTest/WebApp/TestConfig.cs deleted file mode 100644 index bb9c13e..0000000 --- a/HttpClientStudy.UnitTest/WebApp/TestConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace HttpClientStudy.UnitTest -{ - public class TestConfig - { - public const string WebApiBaseUrl = "http://localhost:5189"; - } -} diff --git a/HttpClientStudy.sln b/HttpClientStudy.sln index d592048..35dd6d2 100644 --- a/HttpClientStudy.sln +++ b/HttpClientStudy.sln @@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{56D9132E-6 Docs\说明.md = Docs\说明.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpClientStudy.Config", "HttpClientStudy.Config\HttpClientStudy.Config.csproj", "{78FCC8F1-C196-4D4F-81A0-D0A1E0843AAE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -44,6 +46,10 @@ Global {5FB70481-4D39-4C90-9DAC-9453BBABD860}.Debug|Any CPU.Build.0 = Debug|Any CPU {5FB70481-4D39-4C90-9DAC-9453BBABD860}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FB70481-4D39-4C90-9DAC-9453BBABD860}.Release|Any CPU.Build.0 = Release|Any CPU + {78FCC8F1-C196-4D4F-81A0-D0A1E0843AAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78FCC8F1-C196-4D4F-81A0-D0A1E0843AAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78FCC8F1-C196-4D4F-81A0-D0A1E0843AAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78FCC8F1-C196-4D4F-81A0-D0A1E0843AAE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE