Pārlūkot izejas kodu

邮箱验证配置项更改为数组格式

懒得勤快 2 mēneši atpakaļ
vecāks
revīzija
945ec5dca9

+ 1 - 1
Directory.Build.props

@@ -1,6 +1,6 @@
 <Project>
  <PropertyGroup>
-   <Version>2025.4.6</Version>
+   <Version>2025.5</Version>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
 </Project>

+ 117 - 1
Masuit.Tools.Abstractions/Config/CoreConfig.cs

@@ -1,5 +1,7 @@
 #if NETFRAMEWORK
+using System;
 using System.Configuration;
+using Newtonsoft.Json;
 
 namespace Masuit.Tools.Config
 {
@@ -9,13 +11,33 @@ namespace Masuit.Tools.Config
         {
             return ConfigurationManager.AppSettings.Get(key) ?? defaultValue;
         }
+        public static T Get<T>(string key)
+        {
+            var value = ConfigurationManager.AppSettings.Get(key);
+            if (string.IsNullOrWhiteSpace(value))
+            {
+                return default;
+            }
+
+            try
+            {
+                return JsonConvert.DeserializeObject<T>(value);
+            }
+            catch
+            {
+                return default;
+            }
+        }
     }
 }
 
 #else
 
 using Microsoft.Extensions.Configuration;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System;
+using System.Linq;
 
 namespace Masuit.Tools.Config
 {
@@ -27,7 +49,7 @@ namespace Masuit.Tools.Config
         /// <summary>
         /// 配置对象
         /// </summary>
-        public static IConfiguration Configuration { get; private set; } = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory).AddJsonFile("appsettings.json", true, true).Build();
+        private static IConfiguration Configuration { get; set; } = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory).AddJsonFile("appsettings.json", true, true).Build();
 
         public static string GetConfigOrDefault(string key, string defaultValue = "")
         {
@@ -35,6 +57,100 @@ namespace Masuit.Tools.Config
             return config.IsNullOrEmpty() ? defaultValue : config;
         }
 
+        public static T Get<T>(string key)
+        {
+            var section = Configuration?.GetSection(key);
+            if (section == null)
+            {
+                return default;
+            }
+
+            if (!section.GetChildren().Any())
+            {
+                var value = section.Value ?? Configuration[key];
+                if (string.IsNullOrEmpty(value))
+                {
+                    return default;
+                }
+
+                return ConvertTo<T>(value);
+            }
+
+            var token = BuildToken(section);
+            return token is null ? default : token.ToObject<T>(JsonSerializer.CreateDefault());
+        }
+
+        private static T ConvertTo<T>(string value)
+        {
+            var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
+            try
+            {
+                if (targetType == typeof(string))
+                {
+                    return (T)(object)value;
+                }
+
+                if (targetType.IsEnum)
+                {
+                    return (T)Enum.Parse(targetType, value, true);
+                }
+
+                if (targetType == typeof(Guid))
+                {
+                    return (T)(object)Guid.Parse(value);
+                }
+
+                if (targetType == typeof(bool))
+                {
+                    if (bool.TryParse(value, out var b)) return (T)(object)b;
+                    if (int.TryParse(value, out var bi)) return (T)(object)(bi != 0);
+                }
+
+                if (targetType.IsPrimitive || targetType == typeof(decimal))
+                {
+                    return (T)Convert.ChangeType(value, targetType);
+                }
+            }
+            catch
+            {
+            }
+
+            try
+            {
+                return JsonConvert.DeserializeObject<T>(value);
+            }
+            catch
+            {
+                return default;
+            }
+        }
+
+        private static JToken BuildToken(IConfigurationSection section)
+        {
+            var children = section.GetChildren().ToList();
+            if (children.Count == 0)
+            {
+                return section.Value != null ? JToken.FromObject(section.Value) : null;
+            }
+
+            if (children.All(c => int.TryParse(c.Key, out _)))
+            {
+                var array = new JArray();
+                foreach (var child in children.OrderBy(c => int.Parse(c.Key)))
+                {
+                    array.Add(BuildToken(child));
+                }
+                return array;
+            }
+
+            var obj = new JObject();
+            foreach (var child in children)
+            {
+                obj[child.Key] = BuildToken(child);
+            }
+            return obj;
+        }
+
         /// <summary>
         /// 将配置添加到Masuit.Tools,若未调用,将自动加载默认的appsettings.json
         /// </summary>

+ 7 - 8
Masuit.Tools.Abstractions/Validator/IsEmailAttribute.cs

@@ -1,6 +1,5 @@
 using DnsClient;
 using Masuit.Tools.Config;
-using System;
 using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Net;
@@ -19,12 +18,12 @@ public class IsEmailAttribute : ValidationAttribute
     /// <summary>
     /// 域白名单
     /// </summary>
-    private string WhiteList { get; set; }
+    private string[] WhiteList { get; set; }
 
     /// <summary>
     /// 域黑名单
     /// </summary>
-    private string BlockList { get; set; }
+    private string[] BlockList { get; set; }
 
     /// <summary>
     /// 是否允许为空
@@ -49,8 +48,8 @@ public class IsEmailAttribute : ValidationAttribute
     /// <returns></returns>
     public override bool IsValid(object value)
     {
-        WhiteList = Regex.Replace(ConfigHelper.GetConfigOrDefault("EmailDomainWhiteList"), @"(\w)\.([a-z]+),?", @"$1\.$2!").Trim('!');
-        BlockList = Regex.Replace(ConfigHelper.GetConfigOrDefault("EmailDomainBlockList"), @"(\w)\.([a-z]+),?", @"$1\.$2!").Trim('!');
+        WhiteList = ConfigHelper.Get<string[]>("EmailDomainWhiteList") ?? [];
+        BlockList = ConfigHelper.Get<string[]>("EmailDomainBlockList") ?? [];
         if (AllowEmpty)
         {
             switch (value)
@@ -80,12 +79,12 @@ public class IsEmailAttribute : ValidationAttribute
             return false;
         }
 
-        if (!string.IsNullOrEmpty(WhiteList) && WhiteList.Split('!').Any(item => Regex.IsMatch(email, item)))
+        if (WhiteList.Any(item => Regex.IsMatch(email, item)))
         {
             return true;
         }
 
-        if (!string.IsNullOrEmpty(BlockList) && BlockList.Split(['!', ';'], StringSplitOptions.RemoveEmptyEntries).Any(item => Regex.IsMatch(email, item)))
+        if (BlockList.Any(item => Regex.IsMatch(email, item)))
         {
             ErrorMessage = _customMessage ?? "您输入的邮箱无效,请使用真实有效的邮箱地址!";
             return false;
@@ -96,7 +95,7 @@ public class IsEmailAttribute : ValidationAttribute
         {
             var nslookup = new LookupClient();
             var records = nslookup.Query(email.Split('@')[1], QueryType.MX).Answers.MxRecords().ToList();
-            if (!string.IsNullOrEmpty(BlockList) && records.Exists(r => BlockList.Split('!').Any(item => Regex.IsMatch(r.Exchange.Value, item))))
+            if (records.Exists(r => BlockList.Any(item => Regex.IsMatch(r.Exchange.Value, item))))
             {
                 ErrorMessage = _customMessage ?? "您输入的邮箱无效,请使用真实有效的邮箱地址!";
                 return false;

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

@@ -37,7 +37,7 @@
       </None>
     </ItemGroup>
     <ItemGroup>
-        <PackageReference Include="EPPlus" Version="8.0.8" />
+        <PackageReference Include="EPPlus" Version="8.1.0" />
         <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
     </ItemGroup>
     <ItemGroup>

+ 21 - 2
Masuit.Tools.Net45/Config/CoreConfig.cs

@@ -1,4 +1,5 @@
-using System.Configuration;
+using Newtonsoft.Json;
+using System.Configuration;
 
 namespace Masuit.Tools.Config
 {
@@ -8,5 +9,23 @@ namespace Masuit.Tools.Config
         {
             return ConfigurationManager.AppSettings.Get(key) ?? defaultValue;
         }
+
+        public static T Get<T>(string key)
+        {
+            var value = ConfigurationManager.AppSettings.Get(key);
+            if (string.IsNullOrWhiteSpace(value))
+            {
+                return default;
+            }
+
+            try
+            {
+                return JsonConvert.DeserializeObject<T>(value);
+            }
+            catch
+            {
+                return default;
+            }
+        }
     }
-}
+}

+ 3 - 3
README.md

@@ -92,8 +92,8 @@ mongodb的封装操作类独立包
 
 工具库需要用到外部配置节,.NET Framework项目配置在web.config/app.config的AppSettings配置节中,.NET Core项目配置在appsettings.json中:
 
-1. EmailDomainWhiteList,邮箱校验需要用到的白名单域名,英文逗号分隔,每个元素支持正则表达式,若未配置,则不启用邮箱校验白名单,示例: `"^\\w{1,5}@qq.com,^\\w{1,5}@163.com,^\\w{1,5}@gmail.com,^\\w{1,5}@outlook.com"`
-2. EmailDomainBlockList,邮箱校验需要用到的黑名单域名,英文逗号分隔,每个元素支持正则表达式,且黑名单优先级高于白名单,若未配置,则不启用邮箱校验黑白名单
+1. EmailDomainWhiteList,邮箱校验需要用到的白名单域名正则表达式,数组形式,每个元素支持正则表达式,若未配置,则不启用邮箱校验白名单,示例: `["^\\w{1,5}@qq.com","^\\w{1,5}@163.com","^\\w{1,5}@gmail.com","^\\w{1,5}@outlook.com"]`
+2. EmailDomainBlockList,邮箱校验需要用到的黑名单域名正则表达式,数组形式,每个元素支持正则表达式,且黑名单优先级高于白名单,若未配置,则不启用邮箱校验黑白名单
 
 ```csharp
 public Startup(IConfiguration configuration)
@@ -145,7 +145,7 @@ https://replit.com/@ldqk/MasuitToolsDemo?v=1#main.cs
 ### 1. 检验字符串是否是Email、手机号、URL、IP地址、身份证号等
 
 ```csharp
-var (isMatch, match) = "[email protected]".MatchEmail(); // 可在appsetting.json中添加EmailDomainWhiteList和EmailDomainBlockList配置邮箱域名黑白名单,逗号分隔,如"EmailDomainBlockList": "^\\w{1,5}@qq.com,^\\w{1,5}@163.com,^\\w{1,5}@gmail.com,^\\w{1,5}@outlook.com",
+var (isMatch, match) = "[email protected]".MatchEmail(); // 可在appsetting.json中添加EmailDomainWhiteList和EmailDomainBlockList配置邮箱域名黑白名单正则表达式数组,如"EmailDomainBlockList": ["^\\w{1,5}@qq.com","^\\w{1,5}@163.com","^\\w{1,5}@gmail.com","^\\w{1,5}@outlook.com"]
 bool isInetAddress = "114.114.114.114".MatchInetAddress(); // 匹配IP地址
 bool isUrl = "http://masuit.org/20/history".MatchUrl(); // 匹配url
 bool isPhoneNumber = "15205201520".MatchPhoneNumber(); // 匹配手机号

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

@@ -16,7 +16,7 @@
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
     <PackageReference Include="Moq" Version="4.20.72" />
     <PackageReference Include="xunit" Version="2.9.3" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
+    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>

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

@@ -14,7 +14,7 @@
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
     <PackageReference Include="xunit" Version="2.9.3" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
+    <PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
     </PackageReference>

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

@@ -109,7 +109,7 @@
       <Version>2.0.3</Version>
     </PackageReference>
     <PackageReference Include="xunit.analyzers">
-      <Version>1.23.0</Version>
+      <Version>1.24.0</Version>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <PrivateAssets>all</PrivateAssets>
     </PackageReference>