From 25165949d3db65f9ed3162a7ba7468f0beefa449 Mon Sep 17 00:00:00 2001
From: wanggaofeng <15601716045@163.com>
Date: Fri, 5 Jan 2024 17:25:32 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../Controllers/AdvancedGetController.cs      | 165 ++++++++++++++++--
 .../Models/AdvancedGetInput.cs                |  22 +++
 2 files changed, 170 insertions(+), 17 deletions(-)
 create mode 100644 HttpClientStudy.WebApp/Models/AdvancedGetInput.cs

diff --git a/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs b/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs
index e672c88..468bb79 100644
--- a/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs
+++ b/HttpClientStudy.WebApp/Controllers/AdvancedGetController.cs
@@ -1,4 +1,7 @@
-using System.Text;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+using HttpClientStudy.WebApp.Models;
 
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
@@ -23,38 +26,166 @@ namespace HttpClientStudy.WebApp.Controllers
         }
 
         /// <summary>
-        /// 带请求体数据的Get请求
-        /// (asp.net 3开始,默认不允许Get有Body)
-        /// 注意:不能直接使用模型绑定接收数据,而应以流的方式读取请求体中的数据
+        /// GET请求接口
+        /// 携带请求正文:接口内直接读取Request.Body流
+        /// </summary>
+        [HttpGet]
+        public async Task<IActionResult> GetWithBody()
+        {
+            if (Request.Body == null)
+            { 
+                return new JsonResult(BaseResultUtil.Fail("没有请求体"));
+            }
+
+            if (Request.ContentLength <= 0)
+            {
+                return new JsonResult(BaseResultUtil.Fail("请求体中没有数据"));
+            }
+
+            using (var reader = new StreamReader(Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
+            {
+                var requestBody = await reader.ReadToEndAsync();
+
+                //有关于请求体的业务逻辑
+
+                var result = BaseResultUtil.Success(requestBody);
+                return Ok(result);
+            }
+        }
+
+        /// <summary>
+        /// GET请求接口
+        /// 携带请求正文:使用模型绑定
+        /// </summary>
+        [HttpGet]
+        public async Task<IActionResult> GetWithFormBody([FromForm] int Id,[FromForm] string name)
+        {
+            var paras = $"{nameof(Id)}={Id}&{nameof(name)}={name}";
+            var result = BaseResultUtil.Success(paras);
+
+            await Task.CompletedTask;
+
+            return Ok(result);
+        }
+
+        /// <summary>
+        /// GET请求接口
+        /// 携带请求正文:使用模型绑定
+        /// </summary>
+        [HttpGet]
+        public async Task<IActionResult> GetWithJsonBody([FromBody] AdvancedGetModel vm)
+        {
+            var result = BaseResultUtil.Success(vm);
+
+            await Task.CompletedTask;
+
+            return Ok(result);
+        }
+
+        /// <summary>
+        /// 接收带请求体数据的Get请求
+        /// 携带请求正文:模型绑定后 + 读取Request.Body流(复制流方式)
         /// </summary>
-        /// <returns></returns>
         [HttpGet]
-        public async Task<IActionResult> GetWithBodyAsync()
+        public async Task<IActionResult> GetWithBodyByCopyStream([FromBody] AdvancedGetModel vm)
         {
-            var requestBody = "";
+            if (Request.Body == null)
+            {
+                return new JsonResult(BaseResultUtil.Fail("没有请求体"));
+            }
 
-            //以流方式读取请求体中的数据
-            if (Request.ContentLength>0)
+            if (Request.ContentLength <= 0)
             {
-                using (var reader = new StreamReader(Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
+                return new JsonResult(BaseResultUtil.Fail("请求体中没有数据"));
+            }
+
+            /* 
+             * 复制流方式 
+             */
+
+            // 创建一个内存流存储请求体
+            using (var memStream = new MemoryStream())
+            {
+                // 复制请求体到内存流
+                await HttpContext.Request.Body.CopyToAsync(memStream);
+
+                // 重置内存流的位置,以便从头开始读取
+                memStream.Seek(0, SeekOrigin.Begin);
+
+                // 从内存流中读取文本内容
+                using (var reader = new StreamReader(memStream))
                 {
-                    requestBody = await reader.ReadToEndAsync();
-                    // 现在你有了请求体,可以按照你的需求处理它
+                    var requestBody = await reader.ReadToEndAsync();
+                    // 现在你可以按照你的需要使用requestBody字符串
+                    // 例如,将其作为响应返回
+
+                    var result = BaseResultUtil.Success(requestBody);
+                    return Ok(result);
                 }
             }
+        }
+
+        /// <summary>
+        /// 接收带请求体数据的Get请求
+        /// 携带请求正文:模型绑定后 + 读取Request.Body流(启用倒带功能-推荐)
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet]
+        public async Task<IActionResult> GetWithBodyByEnableBuffering([FromBody] AdvancedGetModel vm)
+        {
+            if (Request.Body == null)
+            {
+                return new JsonResult(BaseResultUtil.Fail("没有请求体"));
+            }
+
+            if (Request.ContentLength <= 0)
+            {
+                return new JsonResult(BaseResultUtil.Fail("请求体中没有数据"));
+            }
+
+            /*
+             * 启用倒带功能,读取Request.Body流
+             * .net core 2.0 
+             * Request.EnableRewind(); 
+             *
+             * .net core 3+
+             * Request.EnableBuffering();
+             */
+
+            Request.EnableBuffering();
+            Request.Body.Position = 0;
+
+            using (var reader = new StreamReader(Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
+            {
+                var requestBody = await reader.ReadToEndAsync();
 
-            var result = BaseResultUtil.Success(requestBody);
+                var result = BaseResultUtil.Success(requestBody);
+                return Ok(result);
+            }
+        }
+
+        /// <summary>
+        /// Post 测试方法
+        /// 表单数据
+        /// </summary>
+        /// <returns></returns>
+        [HttpPost]
+        public IActionResult PostFormData([FromForm,Required]int Id, [FromForm,Required]string name)
+        {
+            var paras = $"{nameof(Id)}={Id}&{nameof(name)}={name}";
+            var result = BaseResultUtil.Success(paras);
             return Ok(result);
         }
 
         /// <summary>
-        /// Post测试方法
+        /// Post 测试方法
+        /// json 数据
         /// </summary>
         /// <returns></returns>
-        [HttpGet]
-        public IActionResult PostDemo()
+        [HttpPost]
+        public IActionResult PostJsonData([FromBody] AdvancedGetModel vm)
         {
-            var result = BaseResultUtil.Success("操作成功");
+            var result = BaseResultUtil.Success(vm);
             return Ok(result);
         }
     }
diff --git a/HttpClientStudy.WebApp/Models/AdvancedGetInput.cs b/HttpClientStudy.WebApp/Models/AdvancedGetInput.cs
new file mode 100644
index 0000000..a87208d
--- /dev/null
+++ b/HttpClientStudy.WebApp/Models/AdvancedGetInput.cs
@@ -0,0 +1,22 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace HttpClientStudy.WebApp.Models
+{
+    /// <summary>
+    /// 高级Get请求参数
+    /// </summary>
+    public class AdvancedGetModel
+    {
+        /// <summary>
+        /// 标识Id
+        /// </summary>
+        [Required]
+        public int Id { get; set; }
+
+        /// <summary>
+        /// 姓名
+        /// </summary>
+        [Required]
+        public required string Name { get; set; }
+    }
+}