diff --git a/Docs/1.0项目管理.dib b/Docs/1.0项目管理.dib index 03ccc24..c366b4e 100644 --- a/Docs/1.0项目管理.dib +++ b/Docs/1.0项目管理.dib @@ -21,7 +21,7 @@ dotnet build ..\HttpClientStudy.sln #!pwsh -# 可以发布整个项目,但要发布到默认目录下 +# 可以发布整个项目,但要发布到默认目录下,指定输出目录的话,会把所有项目都发布到一个目录,造成混乱。 # dotnet publish ..\HttpClientStudy.sln # 分项目发布到Docs目录下 @@ -78,52 +78,55 @@ using System.Diagnostics; using System.Reflection; using Microsoft.Extensions.DependencyInjection; - var pathDic = new Dictionary() - { - //当前运行的exe的完整路径,包含exe文件名,只用于WinForm - {"Application.ExecutablePath",("程序集基完整路径(仅WinForm)", "Application.ExecutablePath 只适用于WinForm") }, +//查看各种程序路径 +{ + var pathDic = new Dictionary() + { + //当前运行的exe的完整路径,包含exe文件名,只用于WinForm + {"Application.ExecutablePath",("程序集基完整路径(仅WinForm)", "Application.ExecutablePath 只适用于WinForm") }, - //程序的启动路径:只用于WinForm - {"Application.StartupPath",("程序集启动路径(仅WinForm)", "Application.StartupPath 只适用于WinForm") }, + //程序的启动路径:只用于WinForm + {"Application.StartupPath",("程序集启动路径(仅WinForm)", "Application.StartupPath 只适用于WinForm") }, - //当前执行的exe或启动项目的路径,通过AppContext - {"AppContext.BaseDirectory",("执行或启动路径", AppContext.BaseDirectory) }, + //当前执行的exe或启动项目的路径,通过AppContext + {"AppContext.BaseDirectory",("执行或启动路径", AppContext.BaseDirectory) }, - //当前执行的exe的目录,不包含exe名,使用AppDomain - {"AppDomain.CurrentDomain.BaseDirectory",("程序集解析程序用于探测程序集的基目录", AppDomain.CurrentDomain.BaseDirectory) }, + //当前执行的exe的目录,不包含exe名,使用AppDomain + {"AppDomain.CurrentDomain.BaseDirectory",("程序集解析程序用于探测程序集的基目录", AppDomain.CurrentDomain.BaseDirectory) }, - //程序安装或启动基目录 包含应用程序的目录的名称 - {"AppDomain.CurrentDomain.SetupInformation.ApplicationBase",("程序安装或启动基目录", AppDomain.CurrentDomain.SetupInformation.ApplicationBase) }, + //程序安装或启动基目录 包含应用程序的目录的名称 + {"AppDomain.CurrentDomain.SetupInformation.ApplicationBase",("程序安装或启动基目录", AppDomain.CurrentDomain.SetupInformation.ApplicationBase) }, - //当前进程的主模块路径,包含exe名 - {"Process.GetCurrentProcess().MainModule.FileName",("当前进程的主模块路径", Process.GetCurrentProcess()?.MainModule?.FileName) }, + //当前进程的主模块路径,包含exe名 + {"Process.GetCurrentProcess().MainModule.FileName",("当前进程的主模块路径", Process.GetCurrentProcess()?.MainModule?.FileName) }, - //环境变量:用户当前工作目录的完整限定路径 - {"Environment.CurrentDirectory",("用户当前工作目录的完整限定路径", Environment.CurrentDirectory) }, + //环境变量:用户当前工作目录的完整限定路径 + {"Environment.CurrentDirectory",("用户当前工作目录的完整限定路径", Environment.CurrentDirectory) }, - //环境变量:当前exe的完整路径,包含exe名,通过命令行参数 - {"Environment.GetCommandLineArgs()[0]",("当前exe的完整路径", Environment.GetCommandLineArgs()[0]) }, + //环境变量:当前exe的完整路径,包含exe名,通过命令行参数 + {"Environment.GetCommandLineArgs()[0]",("当前exe的完整路径", Environment.GetCommandLineArgs()[0]) }, - //当前工作目录的路径(可变) - {"Directory.GetCurrentDirectory",("当前工作目录的路径(可变)", Directory.GetCurrentDirectory()) }, - - //当前Assembly的加载路径,包含dll或exe名 - {"Assembly.GetExecutingAssembly().Location",("当前Assembly的加载路径", Assembly.GetExecutingAssembly().Location) }, + //当前工作目录的路径(可变) + {"Directory.GetCurrentDirectory",("当前工作目录的路径(可变)", Directory.GetCurrentDirectory()) }, + + //当前Assembly的加载路径,包含dll或exe名 + {"Assembly.GetExecutingAssembly().Location",("当前Assembly的加载路径", Assembly.GetExecutingAssembly().Location) }, - //入口程序集的路径 - {"Assembly.GetEntryAssembly().Location",("入口程序集的路径", Assembly.GetEntryAssembly()?.Location) }, + //入口程序集的路径 + {"Assembly.GetEntryAssembly().Location",("入口程序集的路径", Assembly.GetEntryAssembly()?.Location) }, - //已过时:当前程序集的CodeBase路径,可能为file URI格式 - {"Assembly.GetExecutingAssembly().CodeBase",("当前程序集的CodeBase路径", Assembly.GetExecutingAssembly()?.CodeBase) }, + //已过时:当前程序集的CodeBase路径,可能为file URI格式 + {"Assembly.GetExecutingAssembly().CodeBase",("当前程序集的CodeBase路径", Assembly.GetExecutingAssembly()?.CodeBase) }, - //已过时:入口程序集的CodeBase路径,可能为file URI格式 - {"Assembly.GetEntryAssembly().CodeBase",("入口程序集的CodeBase路径", Assembly.GetEntryAssembly()?.CodeBase) }, - }; + //已过时:入口程序集的CodeBase路径,可能为file URI格式 + {"Assembly.GetEntryAssembly().CodeBase",("入口程序集的CodeBase路径", Assembly.GetEntryAssembly()?.CodeBase) }, + }; - var message = string.Empty; - foreach (var item in pathDic) - { - message += $"{item.Key} => {item.Value.path}{Environment.NewLine}"; - } + var message = string.Empty; + foreach (var item in pathDic) + { + message += $"{item.Key} => {item.Value.path}{Environment.NewLine}"; + } - Console.WriteLine(message); + Console.WriteLine(message); +} diff --git a/Docs/1.2.使用准则.ipynb b/Docs/1.2.使用准则.ipynb index 14e92d9..ee4d163 100644 --- a/Docs/1.2.使用准则.ipynb +++ b/Docs/1.2.使用准则.ipynb @@ -21,12 +21,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 0、准备工作:先执行下面单元,以启动WebApi及设置全局对象、方法及其它" + "## 准备工作:先执行下面单元,以启动WebApi及设置全局对象、方法及其它" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -43,6 +43,7 @@ "//全局设置\n", "#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n", "\n", + "//全局命名空间引用\n", "global using System.Net;\n", "global using System.Net.Http;\n", "global using System.Diagnostics;\n", @@ -56,13 +57,20 @@ "global using HttpClientStudy.Core;\n", "global using HttpClientStudy.Core.Utilities;\n", "\n", - "var global_queryDomain = \"soft.pwidc.cn\";\n", - "var global_queryPort = 80;\n", - "var global_queryBaseUrl = $\"http://{global_queryDomain}:{global_queryPort}\";\n", - "\n", - "var global_ips = Dns.GetHostAddresses(global_queryDomain);\n", + "//全局共享变量\n", + "var global_api_config = HttpClientStudy.Config.WebApiConfigManager.GetWebApiConfig();\n", + "var global_ips = Dns.GetHostAddresses(global_api_config.Host);\n", "var global_queryIp = global_ips.First().ToString();\n", - "var global_netstat_filter = $\"{global_queryIp}:{global_queryPort}\";" + "if(global_api_config.Host.Contains(\"localhost\"))\n", + "{\n", + " global_queryIp = \"127.0.0.1\";\n", + "}\n", + "var global_default_page = $\"{global_api_config.PathBase}/Normal/GetAllAccounts\";\n", + "//启动WebAPI程序\n", + "var global_netstat_filter = $\"{global_queryIp}:{global_api_config.Port}\";\n", + "var global_webapi_file = Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe\", Environment.CurrentDirectory); \n", + "var message = AppUtility.RunWebApiExeFile(global_webapi_file);\n", + "Console.WriteLine(message);" ] }, { @@ -89,7 +97,7 @@ "outputs": [], "source": [ "{ //大括号: 1、作用域隔离 2、方便整体代码折叠\n", - " Console.WriteLine(global_queryDomain);\n", + " Console.WriteLine(global_api_config.BaseUrl);\n", "}" ] }, @@ -152,7 +160,7 @@ "$WebAppProc = Get-Process $WebAppProcName -ErrorAction Ignore\n", "if($null -eq $WebAppProc)\n", "{\n", - " Write-Host \"进程没有找到,可能已经\"\n", + " Write-Host \"进程没有找到,可能已经关闭\"\n", "}\n", "else {\n", " $WebAppProc.Kill();\n", @@ -197,13 +205,16 @@ "outputs": [], "source": [ "using System.Net.Http;\n", - "\n", - "var handler = new SocketsHttpHandler\n", "{\n", - " // Recreate every 15 minutes\n", - " PooledConnectionLifetime = TimeSpan.FromMinutes(15) \n", - "};\n", - "var sharedClient = new HttpClient(handler);" + " var handler = new SocketsHttpHandler\n", + " {\n", + " // 15分钟\n", + " PooledConnectionLifetime = TimeSpan.FromMinutes(15) \n", + " };\n", + " var sharedClient = new HttpClient(handler);\n", + "\n", + " sharedClient.Display();\n", + "}" ] }, { @@ -284,15 +295,19 @@ }, "outputs": [], "source": [ - "using System.Net.Http;\n", - "var socketsHandler = new SocketsHttpHandler\n", + "//手动配置 SocketsHttpHandler\n", "{\n", - "\tPooledConnectionLifetime = TimeSpan.FromMinutes(10),\n", - "\tPooledConnectionIdleTimeout = TimeSpan.FromMinutes(5),\n", - "\tMaxConnectionsPerServer = 10\n", - "};\n", - "\t\n", - "var client = new HttpClient(socketsHandler);" + "\tvar socketsHandler = new SocketsHttpHandler\n", + "\t{\n", + "\t\tPooledConnectionLifetime = TimeSpan.FromMinutes(10),\n", + "\t\tPooledConnectionIdleTimeout = TimeSpan.FromMinutes(5),\n", + "\t\tMaxConnectionsPerServer = 10\n", + "\t};\n", + "\t\t\n", + "\tvar client = new HttpClient(socketsHandler);\n", + "\n", + "\tclient.Display();\n", + "}" ] }, { @@ -328,6 +343,8 @@ "source": [ "//测试连接寿命\n", "{\n", + " Console.WriteLine(\"程序运行大约要10-20秒,请在程序退出后,执行下面命令行查看网络情况\");\n", + "\n", " //自定义行为\n", " var socketsHandler = new SocketsHttpHandler\n", " {\n", @@ -341,15 +358,24 @@ " MaxConnectionsPerServer = 10\n", " };\n", "\n", - " var client = new HttpClient(socketsHandler);\n", + " var client = new HttpClient(socketsHandler)\n", + " {\n", + " BaseAddress = new Uri(global_api_config.BaseUrl)\n", + " };\n", + "\n", + " var displayer = \"\".Display();\n", "\n", " for (var i = 0; i < 5; i++)\n", " {\n", - " _ = await client.GetAsync(global_queryBaseUrl);\n", + " if(i>0)\n", + " {\n", + " await Task.Delay(TimeSpan.FromSeconds(2));\n", + " }\n", + " _ = await client.GetAsync(global_default_page);\n", + " displayer.Update(($\"第{i+1}次请求完成\"));\n", + " \n", " await Task.Delay(TimeSpan.FromSeconds(2));\n", " }\n", - "\n", - " Console.WriteLine(\"程序运行大约要10-20秒,请在程序退出后,执行下面命令行查看网络情况\");\n", "}" ] }, @@ -381,7 +407,6 @@ "\n", "Write-Host \"请先执行上面的单元,再执行本单元\"\n", "Write-Host \"网络状态\"\n", - "\n", "netstat -ano | findstr $queryFilter" ] }, @@ -395,7 +420,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -407,33 +432,12 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "47.103.77.66\n", - "程序运行大约要10-20,请在程序退出后,执行下面命令行查看网络情况\n", - " TCP 192.168.1.151:14073 47.103.77.66:80 TIME_WAIT 0\n", - " TCP 192.168.1.151:14079 47.103.77.66:80 TIME_WAIT 0\n", - " TCP 192.168.1.151:14085 47.103.77.66:80 TIME_WAIT 0\n", - " TCP 192.168.1.151:14092 47.103.77.66:80 TIME_WAIT 0\n", - " TCP 192.168.1.151:14101 47.103.77.66:80 ESTABLISHED 39888\n", - "\n" - ] - } - ], + "outputs": [], "source": [ - "{ //\n", - " var ips = await Dns.GetHostAddressesAsync(global_queryDomain);\n", - " string firstIp = ips.FirstOrDefault().ToString();\n", - " \n", - " foreach (var ipAddress in ips)\n", - " {\n", - " Console.WriteLine(ipAddress.MapToIPv4().ToString());\n", - " }\n", - "\n", + "//程序池设置\n", + "{ \n", " //自定义行为\n", + " Console.WriteLine(\"程序运行大约要10-20,请在程序退出后,执行下面命令行查看网络情况\");\n", " var socketsHandler2 = new SocketsHttpHandler\n", " {\n", " PooledConnectionLifetime = TimeSpan.FromSeconds(1),\n", @@ -441,7 +445,12 @@ " MaxConnectionsPerServer = 1\n", " };\n", "\n", - " var client2 = new HttpClient(socketsHandler2);\n", + " var client2 = new HttpClient(socketsHandler2)\n", + " {\n", + " BaseAddress = new Uri(global_api_config.BaseUrl)\n", + " };\n", + "\n", + " var displayer = \"\".Display();\n", "\n", " for (var i = 0; i < 5; i++)\n", " {\n", @@ -449,13 +458,14 @@ " {\n", " await Task.Delay(TimeSpan.FromSeconds(2));\n", " }\n", - " _ = await client2.GetAsync(global_queryBaseUrl);\n", + " _ = await client2.GetAsync(global_default_page);\n", + " displayer.Update(($\"第{i+1}次请求完成\"));\n", + " \n", + " await Task.Delay(TimeSpan.FromSeconds(2));\n", " }\n", - "\n", - " Console.WriteLine(\"程序运行大约要10-20,请在程序退出后,执行下面命令行查看网络情况\");\n", - "\n", + " \n", " //调用命令行,显示查看网络情况\n", - " string command = $\"netstat -ano | findstr {firstIp}\";\n", + " string command = $\"netstat -ano | findstr {global_netstat_filter}\";\n", " \n", " // 创建一个新的ProcessStartInfo对象\n", " ProcessStartInfo startInfo = new ProcessStartInfo(\"cmd\", $\"/c {command}\")\n", @@ -514,7 +524,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -526,20 +536,7 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "开始请求网络...\n", - "共请求了200次,耗时 24989 毫秒\n", - "当前网络状态\n", - " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "/*\n", "\t功能:将MaxConnectionsPerServer限制为2。然后启动200个任务,每个任务都向同一端点发出HTTP请求。这些任务将同时运行。所有请求竞争所花费的时间将写入控制台。\n", @@ -554,11 +551,14 @@ "\t\tMaxConnectionsPerServer = 2\n", "\t};\n", "\n", - "\tvar client = new HttpClient(socketsHandler);\n", + "\tvar client = new HttpClient(socketsHandler)\n", + "\t{\n", + "\t\tBaseAddress = new Uri(global_api_config.BaseUrl)\n", + "\t};\n", "\n", "\tvar sw = Stopwatch.StartNew();\n", "\n", - "\tvar tasks = Enumerable.Range(0, 200).Select(i => client.GetAsync(global_queryBaseUrl));\n", + "\tvar tasks = Enumerable.Range(0, 200).Select(i => client.GetAsync(global_default_page));\n", "\n", "\tawait Task.WhenAll(tasks);\n", "\n", @@ -575,7 +575,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -587,16 +587,7 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n" - ] - } - ], + "outputs": [], "source": [ "# 重新查询当前网络状态\n", "#!set --value @csharp:global_netstat_filter --name queryFilter\n", @@ -612,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -624,30 +615,7 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "开始请求网络...\n", - "共请求了200次,耗时 11781 毫秒\n", - "当前网络状态\n", - " TCP 192.168.1.151:18018 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18019 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18167 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18168 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18169 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18170 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18171 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18172 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18173 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18174 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18175 47.103.77.66:80 ESTABLISHED 32156\n", - " TCP 192.168.1.151:18176 47.103.77.66:80 ESTABLISHED 32156\n", - "\n" - ] - } - ], + "outputs": [], "source": [ "{ //MaxConnectionsPerServer 设置为10:网络连接将增加到10个,耗时将减少到1/4\n", "\tConsole.WriteLine(\"开始请求网络...\");\n", @@ -658,11 +626,16 @@ "\t\tMaxConnectionsPerServer = 10\n", "\t};\n", "\n", - "\tvar client = new HttpClient(socketsHandler);\n", + "\tvar client = new HttpClient(socketsHandler)\n", + "\t{\n", + "\t\tBaseAddress = new Uri(global_api_config.BaseUrl)\n", + "\t};\n", + "\n", + "\t//client.Display();\n", "\n", "\tvar sw = Stopwatch.StartNew();\n", "\n", - "\tvar tasks = Enumerable.Range(0, 200).Select(i => client.GetAsync(global_queryBaseUrl));\n", + "\tvar tasks = Enumerable.Range(0, 200).Select(i => client.GetAsync(global_default_page));\n", "\n", "\tawait Task.WhenAll(tasks);\n", "\n", @@ -714,7 +687,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -738,7 +711,7 @@ " {\n", " using (var client = new HttpClient())\n", " {\n", - " _ = await client.GetAsync(global_queryBaseUrl);\n", + " _ = await client.GetAsync (global_api_config.BaseUrl + global_default_page);\n", " } \n", " Interlocked.Add(ref requestCount, 1);\n", " });\n", @@ -747,10 +720,12 @@ "{ //使用长期客户端\n", " using (var client = new HttpClient())\n", " {\n", + " client.BaseAddress = new Uri(global_api_config.BaseUrl);\n", + " \n", " for(int i=0; i<10; i++)\n", " {\n", " //n次调用,均使用同一个 HttpClient 实例\n", - " _ = await client.GetAsync(global_queryBaseUrl);\n", + " _ = await client.GetAsync(global_default_page);\n", " }\n", " }// 所有调用完成,才释放 HttpClient 实例\n", "}" @@ -765,7 +740,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -777,24 +752,7 @@ "languageId": "polyglot-notebook" } }, - "outputs": [ - { - "data": { - "text/html": [ - "
Installed Packages
  • Microsoft.Extensions.Http.Resilience, 8.6.0
  • Polly, 8.4.1
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "共有227个字符\r\n" - ] - } - ], + "outputs": [], "source": [ "#r \"nuget:Polly\"\n", "#r \"nuget:Microsoft.Extensions.Http.Resilience\"\n", @@ -826,8 +784,9 @@ " #pragma warning restore EXTEXP0001\n", "\n", " var httpClient = new HttpClient(resilienceHandler);\n", + " httpClient.BaseAddress = new Uri(global_api_config.BaseUrl);\n", "\n", - " var response = await httpClient.GetAsync(\"https://www.baidu.com\");\n", + " var response = await httpClient.GetAsync(global_default_page);\n", " var htmlText = await response.Content.ReadAsStringAsync();\n", " Console.WriteLine($\"共有{htmlText.Length}个字符\");\n", "}\n" diff --git a/Docs/1.6.测试.ipynb b/Docs/1.6.测试.ipynb index afae443..2c5474b 100644 --- a/Docs/1.6.测试.ipynb +++ b/Docs/1.6.测试.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -45,14 +45,50 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1.0项目管理.dib\n", + "1.1.概述.ipynb\n", + "1.2.使用准则.ipynb\n", + "1.3.0.基础使用.管理客户端.ipynb\n", + "1.3.1.基础使用.发送请求.ipynb\n", + "1.3.2.基础使用.使用请求体.ipynb\n", + "1.3.3.基础使用.处理响应.ipynb\n", + "1.3.4.基础使用.处理错误.ipynb\n", + "1.3.5.基础使用.使用代理.ipynb\n", + "1.3.6.基础使用.使用Json.ipynb\n", + "1.3.7.基础使用.使用Cookie.ipynb\n", + "1.4.0.高级使用.概述.ipynb\n", + "1.4.1.高级使用.初始化.ipynb\n", + "1.4.2.高级使用.连接池.ipynb\n", + "1.4.3.高级使用.重复使用.ipynb\n", + "1.4.4.高级使用.使用管道.ipynb\n", + "1.4.5.高级使用.类型化客户端.ipynb\n", + "1.4.6..高级使用.工厂模式.ipynb\n", + "1.4.7.高级使用.Polly.ipynb\n", + "1.5.总结.ipynb\n", + "1.6.测试.ipynb\n", + "2.1.内核中的各种路径.ipynb\n", + "Assets\n", + "Publish\n", + "学习.ps1\n", + "说明.md\n", + "\r\n" + ] + } + ], "source": [ "//引用项目\n", "#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n", "\n", "//执行C#工具方法\n", "using HttpClientStudy.Core.Utilities;\n", - "var result = CmdUtility.RunCmd(\"dir\");\n", + "\n", + "\n", + "var result = AppUtility.RunCmd(\"ls\");\n", "Console.WriteLine(result);" ] }, @@ -65,7 +101,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -85,7 +121,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -105,7 +141,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 53, "metadata": { "dotnet_interactive": { "language": "pwsh" @@ -117,19 +153,35 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "进程没有找到,可能已经关闭\r\n" + ] + }, + { + "ename": "Error", + "evalue": "Command failed: SubmitCode: # 关闭项目进程 ...", + "output_type": "error", + "traceback": [ + "Command failed: SubmitCode: # 关闭项目进程 ..." + ] + } + ], "source": [ "# 关闭项目进程\n", "$WebAppProcName =\"HttpClientStudy.WebApp\";\n", "$WebAppProc = Get-Process $WebAppProcName -ErrorAction Ignore\n", "if($null -eq $WebAppProc)\n", "{\n", - " Write-Host \"进程没有找到,可能已经\"\n", + " Write-Host \"进程没有找到,可能已经关闭\"\n", "}\n", "else {\n", " $WebAppProc.Kill();\n", " Write-Host \"$WebAppProcName 进程已退出\"\n", - "}\n" + "}" ] }, { @@ -141,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -153,7 +205,24 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "程序[c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.WebApp\\HttpClientStudy.WebApp.exe]已在新的命令行窗口执行。如果未出现新命令行窗口,可能是程序错误造成窗口闪现!\r\n" + ] + } + ], "source": [ "//启动已发布的WebApi项目\n", "#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n", @@ -162,7 +231,7 @@ " var file = System.IO.Path.GetFullPath(\"./Publish/HttpClientStudy.WebApp/HttpClientStudy.WebApp.exe\",System.Environment.CurrentDirectory);\n", "\n", " file.Display();\n", - " var message = HttpClientStudy.Core.Utilities.DotnetCommondUtility.RunWebApp(file);\n", + " var message = HttpClientStudy.Core.Utilities.AppUtility.RunWebApiExeFile(file);\n", "\n", " Console.WriteLine(message);\n", "}" @@ -170,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -182,14 +251,24 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "配置文件根目录:c:\\Users\\ruyu\\Desktop\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.Core\n", + "WebApi程序[进程号:,进程名:],已关闭!\n" + ] + } + ], "source": [ "//关闭项目进程\n", "#r \"./Publish/HttpClientStudy.Core/HttpClientStudy.Core.dll\"\n", + "\n", "{\n", - " var message = HttpClientStudy.Core.Utilities.DotnetCommondUtility.SopWebApp();\n", + " var message = HttpClientStudy.Core.Utilities.AppUtility.StopWebApiExeFile();\n", " Console.WriteLine(message);\n", - "}\n" + "}" ] } ], diff --git a/HttpClientStudy.Config/ConfigFiles/Config.json b/HttpClientStudy.Config/ConfigFiles/Config.json index 007c557..d09e326 100644 --- a/HttpClientStudy.Config/ConfigFiles/Config.json +++ b/HttpClientStudy.Config/ConfigFiles/Config.json @@ -1,6 +1,9 @@ { "WebApi": { - "BaseUrl": "http://localhost:5189", + "Scheme": "http", + "Host": "127.0.0.1", + "Port": "5189", + "PathBase": "/api", "WebAppMutexName": "HttpClientStudy.WebApp" } } \ No newline at end of file diff --git a/HttpClientStudy.Config/WebApiConfig.cs b/HttpClientStudy.Config/WebApiConfig.cs index 6758831..d24c20b 100644 --- a/HttpClientStudy.Config/WebApiConfig.cs +++ b/HttpClientStudy.Config/WebApiConfig.cs @@ -2,8 +2,37 @@ { public class WebApiConfig { - public string BaseUrl { get; set; } = "http://localhost:5189"; + /// + /// 主机 + /// + public string Host { get; set; } = "localhost"; + /// + /// 端口 + /// + public int Port { get; set; } = 5189; + + /// + /// 协议(http 或者 https) + /// + public string Scheme { get; set; } = "http"; + + /// + /// 基本路径,不以/结尾 + /// + public string PathBase { get; set; } = string.Empty; + + /// + /// + /// + public string BaseUrl + { + get { return $"{Scheme}://{Host}:{Port}"; } + } + + /// + /// WebApi 互斥量 + /// public string WebAppMutexName { get; set; } = "HttpClientStudy.WebApp"; } } diff --git a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs index ed933fb..eae1b14 100644 --- a/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs +++ b/HttpClientStudy.UnitTest/ConfigTest/WebApiConfigTest.cs @@ -50,5 +50,14 @@ namespace HttpClientStudy.UnitTest.ConfigTest Assert.NotNull(webApiConfig); Assert.NotEmpty(webApiConfig.WebAppMutexName); } + + [Fact] + public void DNS_Test() + { + + var ips = Dns.GetHostAddresses(WebApiConfigManager.GetWebApiConfig().Host); + + Assert.NotEmpty(ips); + } } } diff --git a/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs b/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs index 6cf23ab..446e85e 100644 --- a/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs +++ b/HttpClientStudy.UnitTest/HttpClients/BaseHttpClientTest.cs @@ -1,4 +1,6 @@ -namespace HttpClientStudy.UnitTest.HttpClients +using Microsoft.AspNetCore.Http; + +namespace HttpClientStudy.UnitTest.HttpClients { /// /// SimpleHttpClient 测试类 @@ -36,5 +38,20 @@ Assert.IsType(result.Message); Assert.NotEmpty(result.Message); } + + [Fact] + public void Study_Test() + { + BaseHttpClient client = new BaseHttpClient(); + + var result = client.GetJson>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount"); + + Assert.NotNull(result); + Assert.IsAssignableFrom(result); + Assert.Equal(1, result.Code); + Assert.Contains("成功", result.Message); + Assert.IsType(result.Message); + Assert.NotEmpty(result.Message); + } } } diff --git a/HttpClientStudy.WebApp/appsettings.json b/HttpClientStudy.WebApp/appsettings.json index 1885915..5585347 100644 --- a/HttpClientStudy.WebApp/appsettings.json +++ b/HttpClientStudy.WebApp/appsettings.json @@ -3,7 +3,7 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Information" } }, "AllowedHosts": "*"