懒得勤快 преди 1 година
родител
ревизия
ac2f271423

+ 1 - 1
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -18,7 +18,7 @@
         <Product>Masuit.Tools.AspNetCore</Product>
         <PackageId>Masuit.Tools.AspNetCore</PackageId>
         <LangVersion>latest</LangVersion>
-        <Version>1.2.9.9</Version>
+        <Version>1.2.9.10</Version>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <FileVersion>1.1.9</FileVersion>

+ 40 - 40
Masuit.Tools.AspNetCore/ModelBinder/BindType.cs

@@ -6,43 +6,43 @@
 [Flags]
 public enum BindType
 {
-	/// <summary>
-	/// 自动取值(1.取请求数据中的某个值,2.请求数据当成一个对象取值)
-	/// </summary>
-	Default = Body | Query | Form | Header | Cookie | Route,
-
-	/// <summary>
-	/// 从查询字符串获取值
-	/// </summary>
-	Query = 1,
-
-	/// <summary>
-	/// 从请求正文中获取值
-	/// </summary>
-	Body = 2,
-
-	/// <summary>
-	/// 从已发布的表单字段中获取值
-	/// </summary>
-	Form = 4,
-
-	/// <summary>
-	/// 从 HTTP 标头中获取值
-	/// </summary>
-	Header = 8,
-
-	/// <summary>
-	/// 从 Cookie 中取值
-	/// </summary>
-	Cookie = 16,
-
-	/// <summary>
-	/// 从路由数据中获取值
-	/// </summary>
-	Route = 32,
-
-	/// <summary>
-	/// 从依赖关系注入容器中获取类型的实例
-	/// </summary>
-	Services = 64
-}
+    /// <summary>
+    /// 自动取值(1.取请求数据中的某个值,2.请求数据当成一个对象取值)
+    /// </summary>
+    Default = Body | Query | Form | Header | Cookie | Route,
+
+    /// <summary>
+    /// 从查询字符串获取值
+    /// </summary>
+    Query = 1,
+
+    /// <summary>
+    /// 从请求正文中获取值
+    /// </summary>
+    Body = 2,
+
+    /// <summary>
+    /// 从已发布的表单字段中获取值
+    /// </summary>
+    Form = 4,
+
+    /// <summary>
+    /// 从 HTTP 标头中获取值
+    /// </summary>
+    Header = 8,
+
+    /// <summary>
+    /// 从 Cookie 中取值
+    /// </summary>
+    Cookie = 16,
+
+    /// <summary>
+    /// 从路由数据中获取值
+    /// </summary>
+    Route = 32,
+
+    /// <summary>
+    /// 从依赖关系注入容器中获取类型的实例
+    /// </summary>
+    Services = 64
+}

+ 88 - 0
Masuit.Tools.AspNetCore/ModelBinder/BodyOrDefaultBinderMiddleware.cs

@@ -0,0 +1,88 @@
+using System.Net.Mime;
+using System.Text;
+using System.Xml.Linq;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json.Linq;
+
+namespace Masuit.Tools.AspNetCore.ModelBinder;
+
+public sealed class BodyOrDefaultBinderMiddleware(RequestDelegate next, ILogger<BodyOrDefaultBinderMiddleware> logger)
+{
+    public Task Invoke(HttpContext context)
+    {
+        var contentType = context.Request.ContentType;
+        string mediaType;
+        var charSet = "utf-8";
+        if (string.IsNullOrWhiteSpace(contentType))
+        {
+            //表单提交
+            mediaType = "application/x-www-form-urlencoded";
+        }
+        else
+        {
+            var type = new ContentType(contentType);
+            if (!string.IsNullOrWhiteSpace(type.CharSet))
+            {
+                charSet = type.CharSet;
+            }
+
+            mediaType = type.MediaType.ToLower();
+        }
+
+        var encoding = Encoding.GetEncoding(charSet);
+        if (mediaType == "application/x-www-form-urlencoded")
+        {
+            //普通表单提交
+        }
+        else if (mediaType == "multipart/form-data")
+        {
+            //带有文件的表单提交
+        }
+        else if (mediaType == "application/json")
+        {
+            var body = context.GetBodyString(encoding)?.Trim();
+            if (string.IsNullOrWhiteSpace(body))
+            {
+                return next(context);
+            }
+
+            if (!(body.StartsWith("{") && body.EndsWith("}")))
+            {
+                return next(context);
+            }
+
+            try
+            {
+                context.Items.AddOrUpdate("BodyOrDefaultModelBinder@JsonBody", _ => JObject.Parse(body), (_, _) => JObject.Parse(body));
+                return next(context);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, "Parsing json failed:" + body);
+                return next(context);
+            }
+        }
+        else if (mediaType == "application/xml")
+        {
+            var body = context.GetBodyString(encoding)?.Trim();
+            if (string.IsNullOrWhiteSpace(body))
+            {
+                return next(context);
+            }
+
+            try
+            {
+                context.Items.AddOrUpdate("BodyOrDefaultModelBinder@XmlBody", _ => XDocument.Parse(body), (_, _) => XDocument.Parse(body));
+                return next(context);
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex, "Parsing xml failed:" + body);
+                return next(context);
+            }
+        }
+
+        return next(context);
+    }
+}

+ 16 - 0
Masuit.Tools.AspNetCore/ModelBinder/MiddlewareExtensions.cs

@@ -0,0 +1,16 @@
+using Microsoft.AspNetCore.Builder;
+
+namespace Masuit.Tools.AspNetCore.ModelBinder;
+
+public static class MiddlewareExtensions
+{
+    /// <summary>
+    /// 使用自动参数绑定中间件
+    /// </summary>
+    /// <param name="appBuilder"></param>
+    /// <returns></returns>
+    public static IApplicationBuilder UseBodyOrDefaultModelBinder(this IApplicationBuilder appBuilder)
+    {
+        return appBuilder.UseMiddleware<BodyOrDefaultBinderMiddleware>();
+    }
+}

+ 6 - 0
README.md

@@ -1255,6 +1255,12 @@ public class ClassDto
 PM> Install-Package Masuit.Tools.AspNetCore
 ```
 
+Startup配置:
+
+```csharp
+app.UseBodyOrDefaultModelBinder();
+```
+
 在action的参数模型前打上标记:`[FromBodyOrDefault]`即可,示例代码如下:
 
 ```csharp