diff --git a/Docs/1.3.2.基础使用.使用请求数据.ipynb b/Docs/1.3.2.基础使用.使用请求数据.ipynb index 7864369..eaa7551 100644 --- a/Docs/1.3.2.基础使用.使用请求数据.ipynb +++ b/Docs/1.3.2.基础使用.使用请求数据.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 1, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -126,8 +126,14 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 13, "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, "vscode": { "languageId": "polyglot-notebook" } @@ -137,7 +143,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "{\"data\":{\"id\":1,\"name\":\"管理员01\",\"password\":\"123456\",\"role\":\"Admin\"},\"code\":1,\"message\":\"成功\"}\r\n" + "配置文件根目录:e:\\王高峰\\我的项目\\学习项目\\HttpClientStudy\\Docs\\Publish\\HttpClientStudy.Core\n", + "{\"data\":{\"id\":1,\"name\":\"管理员01\",\"password\":\"123456\",\"role\":\"Admin\"},\"code\":1,\"message\":\"成功\"}\n" ] }, { @@ -268,8 +275,14 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 14, "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, "vscode": { "languageId": "polyglot-notebook" } @@ -318,8 +331,14 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 15, "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, "vscode": { "languageId": "polyglot-notebook" } @@ -369,19 +388,48 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 4、使用Form表单" + "## 4、使用请求体" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "把数据放在请求体中,发送到服务端。可以是简单的字符串,也可以是二进制数据(上传文件)、form表单项、编码过的form表单项、json、流式数据等形式,甚至是这个类型的组合。\n", + "\n", + "说下个人的几点理解:\n", + "1、不管哪种请求体数据,都是放在请求体中,以二进制形式通过网络发往服务器,由服务器接收使用。客户端发送请求数据需要与服务端接收相配合;\n", + "2、客户端通过Content-Typey请求头设置,告诉服务端请求发送的是哪种类型的数据;服务端根据Content-Type来识别、解析请求数据。常见的类型有:multipart/form-data、application/x-www-form-urlencoded、application/json、text/plain等;\n", + "3、ASP.NET Core中,默认的请求体类型是FormUrlEncodedContent,所以默认情况下,客户端发送的请求数据是form表单项; asp.net 框架对json格式数据和表单数据进行了特殊处理,支持参数绑定等,可以使用[FromBody]特性,将请求数据绑定到对应的模型上。但普通的文本类型等不支持绑定等功能,需要从请求体中获取原始数据,自行处理。\n", + "4、一次可发送多种格式数据,由统一的分隔符分隔。服务端可以从请求头[] Content-Type: multipart/mixed; boundary=\"d2e38916-df08-4fec-a40e-3e5179736f32\"]拿到分隔符,然后根据分隔符将数据拆分出来。\n", + "\n", + "HttpClient 中,请求体也分为这几种(常见的)类型:\n", + "1. MultipartFormDataContent\n", + "2. FormUrlEncodedContent\n", + "3. JsonContent\n", + "4. StringContent\n", + "5. ByteArrayContent\n", + "6. StreamContent\n", + "7. MultipartContent" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### MultipartFormDataContent :Form表单" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "简单的Form表单,提交数据。其实是把数据放请求值的一种,后页有详细介绍。" + "Form表单,提交数据方式之一。" ] }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 13, "metadata": { "vscode": { "languageId": "polyglot-notebook" @@ -392,7 +440,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "{\"data\":\"Id=1&name=管理员01\",\"code\":1,\"message\":\"成功\"}\r\n" + "{\"data\":\"id=1&name=管理员01\",\"code\":1,\"message\":\"成功\"}\r\n" ] } ], @@ -401,7 +449,7 @@ "* Form表单,提交数据。一般为Put或Post提交。\n", "*/\n", "{\n", - " // 创建一个MultipartFormDataContent对象,用来存入 Form表单独项及值\n", + " // 创建一个 MultipartFormDataContent 对象, 用来存入 Form表单 各项及值\n", " var formContent = new MultipartFormDataContent();\n", " \n", " // 添加表单字段\n", @@ -422,21 +470,25 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 5、使用请求体" + "### FormUrlEncodedContent :Form表单 asp.net core 默认接收方式" ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": null, + "metadata": { + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], "source": [ - "把数据放在请求体中,发送到服务端。可以是简单的字符串,也可以是二进制数据(上传文件)、form表单项、编码过的form表单项、json、流式数据等形式,甚至是这个类型的组合。\n", - "所以请求体也分为这几种(常见的)类型:\n", - "1. StringContent\n", - "2. ByteArrayContent\n", - "3. FormUrlEncodedContent\n", - "4. JsonContent\n", - "5. StreamContent\n", - "6. MultipartContent\n" + "/*\n", + " \n", + "*/\n", + "{\n", + "\n", + "}" ] }, { @@ -452,16 +504,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, "vscode": { "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"data\":\"我是请求体第一段内容\",\"code\":1,\"message\":\"成功\"}\r\n" + ] + } + ], "source": [ + "/*\n", + " \n", + "*/\n", "{\n", - " StringContent content = new StringContent(\"\",Encoding.UTF8, System.Net.Mime.MediaTypeNames.Text.Plain);\n", + " var requestContent = new StringContent(\"我是请求体第一段内容\", Encoding.UTF8, \"text/plain\");\n", + "\n", + " var response = await SharedClient.PostAsync(\"/api/AdvancedPost/TextData\", requestContent);\n", + "\n", + " var content = await response.Content.ReadAsStringAsync();\n", + "\n", + " Console.WriteLine(content);\n", "}" ] } diff --git a/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs b/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs index 61dd2c2..321c456 100644 --- a/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs +++ b/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs @@ -15,12 +15,12 @@ namespace HttpClientStudy.WebApp.Controllers [ApiController] public class AdvancedGetController : ControllerBase { - private ILogger _logger; + private ILogger _logger; /// /// 构造 /// - public AdvancedGetController(ILogger logger) + public AdvancedGetController(ILogger logger) { _logger = logger; } diff --git a/HttpClientStudy.WebApp/Controllers/AdvancedPostController.cs b/HttpClientStudy.WebApp/Controllers/AdvancedPostController.cs new file mode 100644 index 0000000..9cc622a --- /dev/null +++ b/HttpClientStudy.WebApp/Controllers/AdvancedPostController.cs @@ -0,0 +1,95 @@ +using System.ComponentModel.DataAnnotations; +using System.Text; + +using HttpClientStudy.WebApp.Models; + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace HttpClientStudy.WebApp.Controllers +{ + /// + /// 高级Post请求 控制器 + /// + [Route("api/[controller]/[action]")] + [ApiController] + public class AdvancedPostController : ControllerBase + { + private ILogger _logger; + + /// + /// 构造 + /// + public AdvancedPostController(ILogger logger) + { + _logger = logger; + } + + #region 接收请求体数据 + + /// + /// 接收请求体数据 + /// 普通文本:直接从原始请求体获取。不能使用 [FromBody]绑定特性,因为绑定是针对 Form表单、Json格式的特殊数据。 + /// + /// + /// 返回请求体原始数据 + /// + [HttpPost] + public async Task TextData() + { + string content = "请求体没有数据"; + + if (Request.ContentLength>0) + { + byte[] bytes = new byte[(int)Request.ContentLength]; + + await Request.Body.ReadAsync(bytes); + + content = UnicodeEncoding.UTF8.GetString(bytes); + } + + var result = BaseResultUtil.Success(content); + return Ok(result); + } + + /// + /// 接收请求体数据 + /// 表单数据 + /// + /// + [HttpPost] + public IActionResult FormData([FromForm,Required]int id, [FromForm,Required]string name) + { + var paras = $"{nameof(id)}={id}&{nameof(name)}={name}"; + var result = BaseResultUtil.Success(paras); + return Ok(result); + } + + /// + /// 接收请求体数据 + /// 编码后的表单数据 + /// + /// + [HttpPost] + public IActionResult FormUrlEncodedData([FromForm, Required] int id, [FromForm, Required] string name) + { + var paras = $"{nameof(id)}={id}&{nameof(name)}={name}"; + var result = BaseResultUtil.Success(paras); + return Ok(result); + } + + /// + /// 接收请求体数据 + /// json 数据 + /// + /// + [HttpPost] + public IActionResult JsonData([FromBody]AdvancedGetModel? vm) + { + var result = BaseResultUtil.Success(vm); + return Ok(result); + } + + #endregion + } +}