Browse Source

增加了两个Validator
树形结构增加重载参数
ConcurrentBag增加批量添加函数
ASP.NET Core增加fromquery和frombody的同时支持特性BodyAndQueryModelBinder

懒得勤快 3 years ago
parent
commit
6de75d7c79

+ 65 - 0
Masuit.Tools.Abstractions/Extensions/BaseType/IEnumerableExtensions.cs

@@ -1,6 +1,7 @@
 #nullable enable
 #nullable enable
 
 
 using System;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.Linq;
 using System.Linq;
@@ -45,6 +46,34 @@ namespace Masuit.Tools
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// 添加多个元素
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="this"></param>
+        /// <param name="values"></param>
+        public static void AddRange<T>(this ConcurrentBag<T> @this, params T[] values)
+        {
+            foreach (var obj in values)
+            {
+                @this.Add(obj);
+            }
+        }
+
+        /// <summary>
+        /// 添加多个元素
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="this"></param>
+        /// <param name="values"></param>
+        public static void AddRange<T>(this ConcurrentQueue<T> @this, params T[] values)
+        {
+            foreach (var obj in values)
+            {
+                @this.Enqueue(obj);
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// 添加符合条件的多个元素
         /// 添加符合条件的多个元素
         /// </summary>
         /// </summary>
@@ -63,6 +92,42 @@ namespace Masuit.Tools
             }
             }
         }
         }
 
 
+        /// <summary>
+        /// 添加符合条件的多个元素
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="this"></param>
+        /// <param name="predicate"></param>
+        /// <param name="values"></param>
+        public static void AddRangeIf<T>(this ConcurrentBag<T> @this, Func<T, bool> predicate, params T[] values)
+        {
+            foreach (var obj in values)
+            {
+                if (predicate(obj))
+                {
+                    @this.Add(obj);
+                }
+            }
+        }
+
+        /// <summary>
+        /// 添加符合条件的多个元素
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="this"></param>
+        /// <param name="predicate"></param>
+        /// <param name="values"></param>
+        public static void AddRangeIf<T>(this ConcurrentQueue<T> @this, Func<T, bool> predicate, params T[] values)
+        {
+            foreach (var obj in values)
+            {
+                if (predicate(obj))
+                {
+                    @this.Enqueue(obj);
+                }
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// 添加不重复的元素
         /// 添加不重复的元素
         /// </summary>
         /// </summary>

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

@@ -4,7 +4,7 @@
     <LangVersion>latest</LangVersion>
     <LangVersion>latest</LangVersion>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <CodeAnalysisRuleSet />
     <CodeAnalysisRuleSet />
-    <Version>2.4.5.6</Version>
+    <Version>2.4.6</Version>
     <Authors>懒得勤快</Authors>
     <Authors>懒得勤快</Authors>
     <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
     <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
     <Copyright>懒得勤快,长空X</Copyright>
     <Copyright>懒得勤快,长空X</Copyright>

+ 21 - 7
Masuit.Tools.Abstractions/Models/TreeExtensions.cs

@@ -84,15 +84,17 @@ namespace Masuit.Tools.Models
         /// </summary>
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
         /// <param name="items"></param>
         /// <param name="items"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items) where T : class, ITreeChildren<T>
+        public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Action<T, T> optionAction = null) where T : class, ITreeChildren<T>
         {
         {
             var result = new List<T>();
             var result = new List<T>();
             foreach (var item in items)
             foreach (var item in items)
             {
             {
                 result.Add(item);
                 result.Add(item);
                 item.Children ??= new List<T>();
                 item.Children ??= new List<T>();
-                result.AddRange(item.Children.Flatten());
+                item.Children.ForEach(c => optionAction?.Invoke(c, item));
+                result.AddRange(item.Children.Flatten(optionAction));
             }
             }
 
 
             return result;
             return result;
@@ -102,8 +104,10 @@ namespace Masuit.Tools.Models
         /// 平铺开
         /// 平铺开
         /// </summary>
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
+        /// <param name="p"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<T> Flatten<T>(this T p) where T : class, ITreeChildren<T>
+        public static IEnumerable<T> Flatten<T>(this T p, Action<T, T> optionAction = null) where T : class, ITreeChildren<T>
         {
         {
             var result = new List<T>()
             var result = new List<T>()
             {
             {
@@ -113,6 +117,7 @@ namespace Masuit.Tools.Models
             {
             {
                 result.Add(item);
                 result.Add(item);
                 item.Children ??= new List<T>();
                 item.Children ??= new List<T>();
+                item.Children.ForEach(c => optionAction?.Invoke(c, item));
                 result.AddRange(item.Children.Flatten());
                 result.AddRange(item.Children.Flatten());
             }
             }
 
 
@@ -125,13 +130,15 @@ namespace Masuit.Tools.Models
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
         /// <param name="items"></param>
         /// <param name="items"></param>
         /// <param name="selector"></param>
         /// <param name="selector"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> selector)
+        public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> selector, Action<T, T> optionAction = null)
         {
         {
             var result = new List<T>();
             var result = new List<T>();
             foreach (var item in items)
             foreach (var item in items)
             {
             {
                 result.Add(item);
                 result.Add(item);
+                selector(item).ForEach(c => optionAction?.Invoke(c, item));
                 result.AddRange(selector(item).Flatten(selector));
                 result.AddRange(selector(item).Flatten(selector));
             }
             }
 
 
@@ -143,14 +150,16 @@ namespace Masuit.Tools.Models
         /// </summary>
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
         /// <param name="items"></param>
         /// <param name="items"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items) where T : class
+        public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Action<Tree<T>, Tree<T>> optionAction = null) where T : class
         {
         {
             var result = new List<Tree<T>>();
             var result = new List<Tree<T>>();
             foreach (var item in items)
             foreach (var item in items)
             {
             {
                 result.Add(item);
                 result.Add(item);
                 item.Children ??= new List<Tree<T>>();
                 item.Children ??= new List<Tree<T>>();
+                item.Children.ForEach(c => optionAction?.Invoke(c, item));
                 result.AddRange(item.Children.Flatten());
                 result.AddRange(item.Children.Flatten());
             }
             }
 
 
@@ -161,8 +170,10 @@ namespace Masuit.Tools.Models
         /// 平铺开
         /// 平铺开
         /// </summary>
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
+        /// <param name="p"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<Tree<T>> Flatten<T>(this Tree<T> p) where T : class
+        public static IEnumerable<Tree<T>> Flatten<T>(this Tree<T> p, Action<Tree<T>, Tree<T>> optionAction = null) where T : class
         {
         {
             var result = new List<Tree<T>>()
             var result = new List<Tree<T>>()
             {
             {
@@ -172,6 +183,7 @@ namespace Masuit.Tools.Models
             {
             {
                 result.Add(item);
                 result.Add(item);
                 item.Children ??= new List<Tree<T>>();
                 item.Children ??= new List<Tree<T>>();
+                item.Children.ForEach(c => optionAction?.Invoke(c, item));
                 result.AddRange(item.Children.Flatten());
                 result.AddRange(item.Children.Flatten());
             }
             }
 
 
@@ -184,13 +196,15 @@ namespace Masuit.Tools.Models
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="T"></typeparam>
         /// <param name="items"></param>
         /// <param name="items"></param>
         /// <param name="selector"></param>
         /// <param name="selector"></param>
+        /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
         /// <returns></returns>
         /// <returns></returns>
-        public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, IEnumerable<Tree<T>>> selector)
+        public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, IEnumerable<Tree<T>>> selector, Action<Tree<T>, Tree<T>> optionAction = null)
         {
         {
             var result = new List<Tree<T>>();
             var result = new List<Tree<T>>();
             foreach (var item in items)
             foreach (var item in items)
             {
             {
                 result.Add(item);
                 result.Add(item);
+                item.Children.ForEach(c => optionAction?.Invoke(c, item));
                 result.AddRange(selector(item).Flatten(selector));
                 result.AddRange(selector(item).Flatten(selector));
             }
             }
 
 

+ 1 - 1
Masuit.Tools.Abstractions/Validator/ComplexPassword.cs

@@ -91,4 +91,4 @@ namespace Masuit.Tools.Core.Validator
             return false;
             return false;
         }
         }
     }
     }
-}
+}

+ 31 - 0
Masuit.Tools.Abstractions/Validator/EnumOfAttribute.cs

@@ -0,0 +1,31 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Masuit.Tools.Core.Validator;
+
+/// <summary>
+/// 枚举值校验
+/// </summary>
+public class EnumOfAttribute : ValidationAttribute
+{
+    private Type Type { get; set; }
+
+    /// <summary>
+    /// 枚举类型
+    /// </summary>
+    /// <param name="value"></param>
+    public EnumOfAttribute(Type value)
+    {
+        Type = value;
+    }
+
+    public override bool IsValid(object value)
+    {
+        if (value is null)
+        {
+            return true;
+        }
+
+        return Enum.IsDefined(Type, value);
+    }
+}

+ 37 - 0
Masuit.Tools.Abstractions/Validator/MinItemsCountAttribute.cs

@@ -0,0 +1,37 @@
+using System.Collections;
+using System.ComponentModel.DataAnnotations;
+
+namespace Masuit.Tools.Core.Validator;
+
+/// <summary>
+/// 元素个数校验
+/// </summary>
+public class MinItemsCountAttribute : ValidationAttribute
+{
+    private int MinItems { get; }
+
+    /// <summary>
+    /// 最小个数
+    /// </summary>
+    /// <param name="value"></param>
+    public MinItemsCountAttribute(int value)
+    {
+        MinItems = value;
+    }
+
+    /// <summary>
+    /// 校验
+    /// </summary>
+    /// <param name="value"></param>
+    /// <returns></returns>
+    public override bool IsValid(object value)
+    {
+        if (value is null)
+        {
+            return false;
+        }
+
+        var list = value as IList;
+        return list.Count >= MinItems;
+    }
+}

+ 1 - 1
Masuit.Tools.Abstractions/Validator/MinValueAttribute.cs

@@ -43,4 +43,4 @@ namespace Masuit.Tools.Core.Validator
             return base.FormatErrorMessage(name);
             return base.FormatErrorMessage(name);
         }
         }
     }
     }
-}
+}

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

@@ -0,0 +1,38 @@
+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);
+    }
+}

+ 2 - 2
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -18,7 +18,7 @@ github:https://github.com/ldqk/Masuit.Tools
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <RepositoryType>Github</RepositoryType>
         <RepositoryType>Github</RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>2.4.5.6</Version>
+        <Version>2.4.6</Version>
         <FileVersion>2.4.5.6</FileVersion>
         <FileVersion>2.4.5.6</FileVersion>
         <Company>masuit.com</Company>
         <Company>masuit.com</Company>
         <AssemblyVersion>2.4.5.6</AssemblyVersion>
         <AssemblyVersion>2.4.5.6</AssemblyVersion>
@@ -64,7 +64,7 @@ github:https://github.com/ldqk/Masuit.Tools
     </ItemGroup>
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net6'">
     <ItemGroup Condition=" '$(TargetFramework)' == 'net6'">
         <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
         <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
         <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0" />
         <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0" />
         <PackageReference Include="Microsoft.Extensions.Http" Version="6.0" />
         <PackageReference Include="Microsoft.Extensions.Http" Version="6.0" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="6.0" />

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

@@ -28,7 +28,7 @@
         <DocumentationFile>.\Masuit.Tools.Excel.xml</DocumentationFile>
         <DocumentationFile>.\Masuit.Tools.Excel.xml</DocumentationFile>
     </PropertyGroup>
     </PropertyGroup>
     <ItemGroup>
     <ItemGroup>
-        <PackageReference Include="EPPlus" Version="5.8.3" />
+        <PackageReference Include="EPPlus" Version="5.8.4" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
         <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
         <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
     </ItemGroup>
     </ItemGroup>

+ 1 - 1
Masuit.Tools.Net45/package.nuspec

@@ -4,7 +4,7 @@
     <!--*-->
     <!--*-->
     <id>Masuit.Tools.Net45</id>
     <id>Masuit.Tools.Net45</id>
     <!--*-->
     <!--*-->
-    <version>2.4.5.5</version>
+    <version>2.4.6</version>
     <title>Masuit.Tools</title>
     <title>Masuit.Tools</title>
     <!--*-->
     <!--*-->
     <authors>懒得勤快</authors>
     <authors>懒得勤快</authors>

+ 1 - 1
Masuit.Tools/package.nuspec

@@ -4,7 +4,7 @@
     <!--*-->
     <!--*-->
     <id>Masuit.Tools.Net</id>
     <id>Masuit.Tools.Net</id>
     <!--*-->
     <!--*-->
-    <version>2.4.5.6</version>
+    <version>2.4.6</version>
     <title>Masuit.Tools</title>
     <title>Masuit.Tools</title>
     <!--*-->
     <!--*-->
     <authors>懒得勤快</authors>
     <authors>懒得勤快</authors>

+ 1 - 1
Test/Masuit.Tools.Core.Test/Masuit.Tools.Core.Test.csproj

@@ -9,7 +9,7 @@
   </PropertyGroup>
   </PropertyGroup>
 
 
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.0" />
+    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.1" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
     <PackageReference Include="xunit" Version="2.4.1" />
     <PackageReference Include="xunit" Version="2.4.1" />