diff --git a/HttpClientStudy.Config/WebApiOption.cs b/HttpClientStudy.Config/WebApiConfig.cs similarity index 76% rename from HttpClientStudy.Config/WebApiOption.cs rename to HttpClientStudy.Config/WebApiConfig.cs index ec95aa9..9f2aca1 100644 --- a/HttpClientStudy.Config/WebApiOption.cs +++ b/HttpClientStudy.Config/WebApiConfig.cs @@ -1,6 +1,6 @@ namespace HttpClientStudy.Config { - public class WebApiOption + public class WebApiConfig { public string BaseUrl { get; set; } } diff --git a/HttpClientStudy.Config/WebApiConfigExtensions.cs b/HttpClientStudy.Config/WebApiConfigExtensions.cs index 50f87a6..1cca332 100644 --- a/HttpClientStudy.Config/WebApiConfigExtensions.cs +++ b/HttpClientStudy.Config/WebApiConfigExtensions.cs @@ -45,7 +45,7 @@ namespace HttpClientStudy.Config services.AddOptions(); var configuration = services.BuildServiceProvider().GetService(); - services.Configure(configuration.GetSection("WebApi")); + services.Configure(configuration.GetSection("WebApi")); return services; } diff --git a/HttpClientStudy.Config/WebApiConfigManager.cs b/HttpClientStudy.Config/WebApiConfigManager.cs new file mode 100644 index 0000000..a7d1db9 --- /dev/null +++ b/HttpClientStudy.Config/WebApiConfigManager.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace HttpClientStudy.Config +{ + public static class WebApiConfigManager + { + public static WebApiConfig GetWebApiConfig() + { + return GetWebApiConfigOption().CurrentValue; + } + + public static IOptionsMonitor GetWebApiConfigOption() + { + ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddWebApiConfigration(); + + ServiceCollection services = new ServiceCollection(); + services.AddSingleton(configurationBuilder.Build()); + services.AddWebApiOptions(); + + var webApiConfigOption = services.BuildServiceProvider().GetService>(); + if (webApiConfigOption == null) + { + throw new OptionsValidationException(nameof(webApiConfigOption), typeof(IOptions), new[] { "获取配置异常"}); + } + + return webApiConfigOption; + } + } +} diff --git a/HttpClientStudy.Core/HttpError.cs b/HttpClientStudy.Core/HttpError.cs index 1393149..a9ce7c1 100644 --- a/HttpClientStudy.Core/HttpError.cs +++ b/HttpClientStudy.Core/HttpError.cs @@ -1,33 +1,70 @@ -namespace HttpClientStudy.Core +using HttpClientStudy.Config; + +using Microsoft.Extensions.Options; + +namespace HttpClientStudy.Core { /// /// Http 错误处理 + /// + /// + /// 常见方式 + /// (仅个人见解) + /// + /// + /// HtppClient 提供的状态码、EnsureSuccessStatusCode()等机制 + /// (适用HttpClient内部错误) + /// + /// + /// Try Catch 方式 + /// (适用外部) + /// + /// + /// 使用 Polly 类库 + /// (更多功能) + /// + /// /// + /// + /// 简化处理 + /// public class HttpError { // 定义一个 HttpClient 实例,共享 public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) }) { - BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl) + BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl) }; - public async Task UrlNotFoundAsync() + /// + /// 未知主机错误 + /// + /// + public async Task UnknownHostAsync() { - var response = await HttpClient.GetAsync("http://www.notingxxxxxxxx.com/404.html"); - - response.EnsureSuccessStatusCode(); + var response = await HttpClient.GetAsync("http://www.unknowhost_nonono.com/404.html"); return response.StatusCode; } + /// + /// 404错误 + /// + /// public async Task Http404Async() - { - var response = await HttpClient.GetAsync("http://www.baidu.com/404.html"); - - response.EnsureSuccessStatusCode(); - + { + var response = await HttpClient.GetAsync("/404.html"); return response.StatusCode; } + /// + /// 服务器错误 + /// + /// + public async Task Http500Async() + { + var response = await HttpClient.GetAsync("/api/ErrorDemo/Error500"); + return response.StatusCode; + } } } diff --git a/HttpClientStudy.Core/WebApiConfig.cs b/HttpClientStudy.Core/WebApiConfig.cs deleted file mode 100644 index b6c1808..0000000 --- a/HttpClientStudy.Core/WebApiConfig.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace HttpClientStudy.Core -{ - public class WebApiConfig - { - public const string WebApiBaseUrl = "http://localhost:5189"; - } -} diff --git a/HttpClientStudy.Service/HttpClientStudy.Service.csproj b/HttpClientStudy.Service/HttpClientStudy.Service.csproj index ef7db5c..4417aa5 100644 --- a/HttpClientStudy.Service/HttpClientStudy.Service.csproj +++ b/HttpClientStudy.Service/HttpClientStudy.Service.csproj @@ -8,7 +8,6 @@ - diff --git a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs index 435f966..c3ae6b9 100644 --- a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs +++ b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs @@ -28,13 +28,24 @@ namespace HttpClientStudy.UnitTest.ConfigTest services.AddWebApiOptions(); var provider = services.BuildServiceProvider(); - IOptions webApiOptions = provider.GetService>(); + IOptions webApiOptions = provider.GetService>(); var webApiConfig = webApiOptions.Value; Assert.NotNull(webApiOptions); Assert.NotEmpty(webApiConfig.BaseUrl); + } + + [Fact] + public void WebApiOption_Test2() + { + IOptionsMonitor webApiMonitor = WebApiConfigManager.GetWebApiConfigOption(); + + Assert.NotNull(webApiMonitor); + + var webApiConfig = webApiMonitor.CurrentValue; + Assert.NotNull(webApiConfig); } } } diff --git a/HttpClientStudy.UnitTest/GlobalUsings.cs b/HttpClientStudy.UnitTest/GlobalUsings.cs index a3c1bb8..6e54396 100644 --- a/HttpClientStudy.UnitTest/GlobalUsings.cs +++ b/HttpClientStudy.UnitTest/GlobalUsings.cs @@ -19,6 +19,8 @@ global using Xunit.Serialization; global using HttpClientStudy.Model; +global using HttpClientStudy.Config; + global using HttpClientStudy.Core; global using HttpClientStudy.Core.UseJson; global using HttpClientStudy.Core.HttpRequests; diff --git a/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj b/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj index 9aecc3c..a43d6b5 100644 --- a/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj +++ b/HttpClientStudy.UnitTest/HttpClientStudy.UnitTest.csproj @@ -24,9 +24,6 @@ - - - diff --git a/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs b/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs index 35ad031..53d5d73 100644 --- a/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/GetWithBodyTest.cs @@ -6,6 +6,9 @@ using System.Security.Cryptography.Xml; using System.Text; using System.Text.Unicode; using System.Threading.Tasks; + +using HttpClientStudy.Config; + using Newtonsoft.Json; namespace HttpClientStudy.UnitTest.HttpClients @@ -20,7 +23,7 @@ namespace HttpClientStudy.UnitTest.HttpClients /// public static HttpClient GetHttpClient = new HttpClient() { - BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl), + BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl), }; /// diff --git a/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs b/HttpClientStudy.UnitTest/HttpClients/HttpClientQuestTest.cs index 07ff344..ff31285 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(WebApiConfig.WebApiBaseUrl + "/api/health"); + var responseMessage = await httpClient.GetAsync(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/health"); responseMessage.EnsureSuccessStatusCode(); } @@ -64,7 +64,7 @@ namespace HttpClientStudy.UnitTest.HttpClients { HttpClient httpClient = new HttpClient() { - BaseAddress = new Uri(WebApiConfig.WebApiBaseUrl) + BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl) }; for (int i = 0; i < 100; i++) { diff --git a/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/PipelineClientTest.cs index 2da25ec..79e6ee3 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(WebApiConfig.WebApiBaseUrl + "/api/health"); + var sd = await httpClient.GetAsync(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/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(WebApiConfig.WebApiBaseUrl + "/api/health"); + var r = await client.GetAsync(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/health"); r.EnsureSuccessStatusCode(); } } diff --git a/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/SimpleHttpClientTest.cs index 3ede1e5..bafefdc 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(WebApiConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); + var result = client.Get(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); Assert.NotNull(result); Assert.NotEmpty(result); @@ -27,7 +27,7 @@ { SimpleHttpClient client = new SimpleHttpClient(); - var result = client.GetJson>(WebApiConfig.WebApiBaseUrl + "/api/Simple/GetAccount"); + var result = client.GetJson>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); Assert.NotNull(result); Assert.IsAssignableFrom(result); diff --git a/HttpClientStudy.UnitTest/HttpErrorTest.cs b/HttpClientStudy.UnitTest/HttpErrorTest.cs index 3311e7b..97b00fd 100644 --- a/HttpClientStudy.UnitTest/HttpErrorTest.cs +++ b/HttpClientStudy.UnitTest/HttpErrorTest.cs @@ -17,13 +17,29 @@ namespace HttpClientStudy.UnitTest } [Fact] - public async void Test() + public async Task UnknownHost_Test() + { + Func func = _httpError.UnknownHostAsync; + + await Assert.ThrowsAsync(func); + } + + [Fact] + public async Task Http404_Test() { var code = await _httpError.Http404Async(); Assert.Equal(HttpStatusCode.NotFound, code); } + [Fact] + public async Task Http500_Test() + { + var code = await _httpError.Http500Async(); + + Assert.Equal(HttpStatusCode.InternalServerError, code); + } + public void Dispose() { diff --git a/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs b/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs new file mode 100644 index 0000000..7f4e212 --- /dev/null +++ b/HttpClientStudy.WebApp/Controllers/ErrorDemoController.cs @@ -0,0 +1,43 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Net.Http.Headers; +using System.Security.Claims; +using System.Text; + +using HttpClientStudy.Model; +using HttpClientStudy.WebApp.Models; + +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.IdentityModel.Tokens; + +namespace HttpClientStudy.WebApp.Controllers +{ + /// + /// 错误和异常处理 控制器 + /// + [Route("api/[controller]/[action]")] + [ApiController] + public class ErrorDemoController : ControllerBase + { + /// + /// 构造 + /// + public ErrorDemoController() { } + + /// + /// 500错误 + /// + /// + //[AllowAnonymous] + [HttpGet] + public IActionResult Error500() + { + throw new System.Exception("服务器异常"); + + var result = BaseResultUtil.Success("服务器异常"); + return new JsonResult(result); + } + } +} diff --git a/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj b/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj index 1a6bf01..4d8e356 100644 --- a/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj +++ b/HttpClientStudy.WebApp/HttpClientStudy.WebApp.csproj @@ -15,8 +15,6 @@ - -