소스 검색

增加Masuit.Tools.AspNetCore包

懒得勤快 3 년 전
부모
커밋
653f948484

+ 5 - 3
Masuit.Tools.Abstractions/Extensions/BaseType/StringExtensions.cs

@@ -185,7 +185,7 @@ namespace Masuit.Tools
         /// <returns></returns>
         public static bool IsNullOrEmpty(this string s)
         {
-            return string.IsNullOrEmpty(s);
+            return string.IsNullOrEmpty(s) || s.Equals("null", StringComparison.CurrentCultureIgnoreCase);
         }
 
         /// <summary>
@@ -584,6 +584,7 @@ namespace Masuit.Tools
         #endregion Crc32
 
         #region 权威校验中国专利申请号/专利号
+
         /// <summary>
         /// 中国专利申请号(授权以后就是专利号)由两种组成
         /// 2003年9月30号以前的9位(不带校验位是8号),校验位之前可能还会有一个点,例如:00262311, 002623110 或 00262311.0
@@ -696,5 +697,6 @@ $", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase | RegexOption
             return s.Length > length ? s.Substring(0, length) : s;
         }
     }
-    #endregion
-}
+
+    #endregion 权威校验中国专利申请号/专利号
+}

+ 38 - 0
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+    <PropertyGroup>
+        <TargetFrameworks>netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
+        <Description>
+            包含一些AspNetCore常用的工具类。ModelBinder等
+            官网教程:https://ldqk.org/55
+            github:https://github.com/ldqk/Masuit.Tools
+        </Description>
+        <Copyright>Copyright © 懒得勤快</Copyright>
+        <PackageProjectUrl>https://github.com/ldqk/Masuit.Tools</PackageProjectUrl>
+        <PackageTags>Masuit.Tools,工具库,Utility,Crypt,Extensions</PackageTags>
+        <PackageReleaseNotes>如有问题请联系作者QQ:3444764617,或者到项目的github反馈问题,详细的API文档在github上:https://github.com/ldqk/Masuit.Tools</PackageReleaseNotes>
+        <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
+        <PackageLicenseUrl>https://github.com/ldqk/Masuit.Tools/blob/master/LICENSE</PackageLicenseUrl>
+        <Product>Masuit.Tools.AspNetCore</Product>
+        <PackageId>Masuit.Tools.AspNetCore</PackageId>
+        <LangVersion>latest</LangVersion>
+        <RepositoryType>Github</RepositoryType>
+        <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
+        <Version>1.0</Version>
+        <FileVersion>1.0</FileVersion>
+        <Company>masuit.com</Company>
+        <AssemblyVersion>1.0</AssemblyVersion>
+        <Authors>懒得勤快</Authors>
+        <RepositoryUrl>https://github.com/ldqk/Masuit.Tools</RepositoryUrl>
+        <EmbedUntrackedSources>true</EmbedUntrackedSources>
+        <IncludeSymbols>true</IncludeSymbols>
+        <SymbolPackageFormat>snupkg</SymbolPackageFormat>
+        <OutputType>Library</OutputType>
+        <IsPackable>true</IsPackable>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\Masuit.Tools.Core\Masuit.Tools.Core.csproj" />
+    </ItemGroup>
+
+</Project>

+ 23 - 0
Masuit.Tools.AspNetCore/ModelBinder/BodyOrDefaultBindingSource.cs

@@ -0,0 +1,23 @@
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+
+namespace Masuit.Tools.AspNetCore.ModelBinder
+{
+    public class BodyOrDefaultBindingSource : BindingSource
+    {
+        public static readonly BindingSource BodyOrDefault = new BodyOrDefaultBindingSource(
+            "BodyOrDefault",
+            "BodyOrDefault",
+            true,
+            true
+            );
+
+        public BodyOrDefaultBindingSource(string id, string displayName, bool isGreedy, bool isFromRequest) : base(id, displayName, isGreedy, isFromRequest)
+        {
+        }
+
+        public override bool CanAcceptDataFrom(BindingSource bindingSource)
+        {
+            return bindingSource == Body || bindingSource == this;
+        }
+    }
+}

+ 91 - 0
Masuit.Tools.AspNetCore/ModelBinder/BodyOrDefaultModelBinder.cs

@@ -0,0 +1,91 @@
+using System;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace Masuit.Tools.AspNetCore.ModelBinder
+{
+    public class BodyOrDefaultModelBinder : IModelBinder
+    {
+        private readonly IModelBinder _bodyBinder;
+        private readonly IModelBinder _complexBinder;
+
+        public BodyOrDefaultModelBinder(IModelBinder bodyBinder, IModelBinder complexBinder)
+        {
+            _bodyBinder = bodyBinder;
+            _complexBinder = complexBinder;
+        }
+
+        public async Task BindModelAsync(ModelBindingContext bindingContext)
+        {
+            var request = bindingContext.HttpContext.Request;
+            request.EnableBuffering();
+            var buffer = new byte[Convert.ToInt32(request.ContentLength)];
+            _ = await request.Body.ReadAsync(buffer, 0, buffer.Length);
+            var text = Encoding.UTF8.GetString(buffer);
+            request.Body.Position = 0;
+
+            if (bindingContext.ModelType.IsPrimitive || bindingContext.ModelType == typeof(string) || bindingContext.ModelType.IsEnum || bindingContext.ModelType == typeof(DateTime) || bindingContext.ModelType == typeof(Guid))
+            {
+                var parameter = bindingContext.ModelMetadata.ParameterName;
+                var value = "";
+                if (request.Query.ContainsKey(parameter))
+                {
+                    value = request.Query[parameter] + "";
+                }
+                else if (request.ContentType.StartsWith("application/json"))
+                {
+                    value = JObject.Parse(text)[parameter] + "";
+                }
+                else if (request.HasFormContentType)
+                {
+                    value = request.Form[bindingContext.ModelMetadata.ParameterName] + "";
+                }
+
+                if (value.TryConvertTo(bindingContext.ModelType, out var result))
+                {
+                    bindingContext.Result = ModelBindingResult.Success(result);
+                }
+                return;
+            }
+
+            if (request.HasFormContentType)
+            {
+                if (bindingContext.ModelType.IsClass)
+                {
+                    await DefaultBindModel(bindingContext);
+                }
+                else
+                {
+                    bindingContext.Result = ModelBindingResult.Success(request.Form[bindingContext.ModelMetadata.ParameterName].ToString().ConvertTo(bindingContext.ModelType));
+                }
+                return;
+            }
+
+            try
+            {
+                bindingContext.Result = ModelBindingResult.Success(JsonConvert.DeserializeObject(text, bindingContext.ModelType) ?? request.Query[bindingContext.ModelMetadata.ParameterName!].ToString().ConvertTo(bindingContext.ModelType));
+            }
+            catch
+            {
+                await DefaultBindModel(bindingContext);
+            }
+        }
+
+        private async Task DefaultBindModel(ModelBindingContext bindingContext)
+        {
+            await _bodyBinder.BindModelAsync(bindingContext);
+
+            if (bindingContext.Result.IsModelSet)
+            {
+                return;
+            }
+
+            bindingContext.ModelState.Clear();
+            await _complexBinder.BindModelAsync(bindingContext);
+        }
+    }
+}

+ 37 - 0
Masuit.Tools.AspNetCore/ModelBinder/BodyOrDefaultModelBinderProvider.cs

@@ -0,0 +1,37 @@
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
+#if NET5_0_OR_GREATER
+
+using ComplexDataModelBinderProvider = Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinderProvider;
+
+#else
+
+using ComplexDataModelBinderProvider = Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinderProvider;
+
+#endif
+
+namespace Masuit.Tools.AspNetCore.ModelBinder
+{
+    public class BodyOrDefaultModelBinderProvider : IModelBinderProvider
+    {
+        private BodyModelBinderProvider _bodyModelBinderProvider;
+        private ComplexDataModelBinderProvider _complexDataModelBinderProvider;
+
+        public BodyOrDefaultModelBinderProvider(BodyModelBinderProvider bodyModelBinderProvider, ComplexDataModelBinderProvider complexDataModelBinderProvider)
+        {
+            _bodyModelBinderProvider = bodyModelBinderProvider;
+            _complexDataModelBinderProvider = complexDataModelBinderProvider;
+        }
+
+        public IModelBinder GetBinder(ModelBinderProviderContext context)
+        {
+            if (context.BindingInfo.BindingSource != null && context.BindingInfo.BindingSource.CanAcceptDataFrom(BodyOrDefaultBindingSource.BodyOrDefault))
+            {
+                var bodyBinder = _bodyModelBinderProvider.GetBinder(context);
+                var complexBinder = _complexDataModelBinderProvider.GetBinder(context);
+                return new BodyOrDefaultModelBinder(bodyBinder, complexBinder);
+            }
+            return null;
+        }
+    }
+}

+ 29 - 0
Masuit.Tools.AspNetCore/ModelBinder/BodyOrDefaultModelBinderProviderSetup.cs

@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
+#if NET5_0_OR_GREATER
+
+using ComplexDataModelBinderProvider = Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexObjectModelBinderProvider;
+
+#else
+
+using ComplexDataModelBinderProvider = Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinderProvider;
+
+#endif
+
+namespace Masuit.Tools.AspNetCore.ModelBinder
+{
+    public static class BodyOrDefaultModelBinderProviderSetup
+    {
+        public static void InsertBodyOrDefaultBinding(this IList<IModelBinderProvider> providers)
+        {
+            var bodyProvider = providers.Single(provider => provider.GetType() == typeof(BodyModelBinderProvider)) as BodyModelBinderProvider;
+            var complexDataProvider = providers.OfType<ComplexDataModelBinderProvider>().Single();
+
+            var bodyOrDefault = new BodyOrDefaultModelBinderProvider(bodyProvider, complexDataProvider);
+
+            providers.Insert(0, bodyOrDefault);
+        }
+    }
+}

+ 11 - 0
Masuit.Tools.AspNetCore/ModelBinder/FromBodyOrDefaultAttribute.cs

@@ -0,0 +1,11 @@
+using System;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+
+namespace Masuit.Tools.AspNetCore.ModelBinder
+{
+    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
+    public class FromBodyOrDefaultAttribute : Attribute, IBindingSourceMetadata
+    {
+        public BindingSource BindingSource => BodyOrDefaultBindingSource.BodyOrDefault;
+    }
+}

+ 12 - 0
Masuit.Tools.AspNetCore/Properties/launchSettings.json

@@ -0,0 +1,12 @@
+{
+  "profiles": {
+    "Masuit.Tools.AspNetCore": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "applicationUrl": "https://localhost:63779;http://localhost:63780"
+    }
+  }
+}

+ 0 - 38
Masuit.Tools.Core/AspNetCore/BodyAndQueryModelBinder.cs

@@ -1,38 +0,0 @@
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Newtonsoft.Json;
-using System.IO;
-using System.Threading.Tasks;
-using System.Web;
-using System;
-using System.Linq;
-
-namespace Masuit.Tools.Core.AspNetCore;
-
-public class BodyAndQueryModelBinder<T> : IModelBinder where T : IConvertible
-{
-    public async Task BindModelAsync(ModelBindingContext bindingContext)
-    {
-        var body = bindingContext.HttpContext.Request.Body;
-        using var reader = new StreamReader(body);
-        var text = await reader.ReadToEndAsync();
-
-        if (typeof(T).IsPrimitive || typeof(T) == typeof(string) || typeof(T).IsEnum || typeof(T) == typeof(DateTime) || typeof(T) == typeof(Guid))
-        {
-            bindingContext.Result = ModelBindingResult.Success(JsonConvert.DeserializeObject<T>(text) ?? bindingContext.HttpContext.Request.Query[bindingContext.ModelMetadata.ParameterName!].ToString().ConvertTo<T>());
-            return;
-        }
-
-        var dict = HttpUtility.ParseQueryString(bindingContext.HttpContext.Request.QueryString.ToString());
-        var contract = JsonConvert.DeserializeObject<T>(text) ?? JsonConvert.DeserializeObject<T>(dict.Cast<string>().ToDictionary(k => k, k => dict[k]).ToJsonString());
-        var properties = typeof(T).GetProperties();
-        foreach (var property in properties)
-        {
-            var valueProvider = bindingContext.ValueProvider.GetValue(property.Name);
-            if (string.IsNullOrEmpty(valueProvider.FirstValue))
-            {
-                property.SetValue(contract, valueProvider.FirstValue);
-            }
-        }
-        bindingContext.Result = ModelBindingResult.Success(contract);
-    }
-}

+ 8 - 2
Masuit.Tools.sln

@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30225.117
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32210.238
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masuit.Tools", "Masuit.Tools\Masuit.Tools.csproj", "{275D5A0D-C49C-497E-A4B5-F40285C2495F}"
 EndProject
@@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masuit.Tools.Excel", "Masui
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masuit.Tools.Net45", "Masuit.Tools.Net45\Masuit.Tools.Net45.csproj", "{F51077A5-1CCA-4576-89BB-5447AC3D8DBC}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masuit.Tools.AspNetCore", "Masuit.Tools.AspNetCore\Masuit.Tools.AspNetCore.csproj", "{73BA93B7-C6AE-4B39-892E-3596D91BF96C}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -77,6 +79,10 @@ Global
 		{F51077A5-1CCA-4576-89BB-5447AC3D8DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F51077A5-1CCA-4576-89BB-5447AC3D8DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F51077A5-1CCA-4576-89BB-5447AC3D8DBC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{73BA93B7-C6AE-4B39-892E-3596D91BF96C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{73BA93B7-C6AE-4B39-892E-3596D91BF96C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{73BA93B7-C6AE-4B39-892E-3596D91BF96C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{73BA93B7-C6AE-4B39-892E-3596D91BF96C}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE