Skip to content

Commit 945ec5d

Browse files
committed
邮箱验证配置项更改为数组格式
1 parent 7c08a38 commit 945ec5d

File tree

9 files changed

+153
-19
lines changed

9 files changed

+153
-19
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>2025.4.6</Version>
3+
<Version>2025.5</Version>
44
<Deterministic>true</Deterministic>
55
</PropertyGroup>
66
</Project>

Masuit.Tools.Abstractions/Config/CoreConfig.cs

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#if NETFRAMEWORK
2+
using System;
23
using System.Configuration;
4+
using Newtonsoft.Json;
35

46
namespace Masuit.Tools.Config
57
{
@@ -9,13 +11,33 @@ public static string GetConfigOrDefault(string key, string defaultValue = "")
911
{
1012
return ConfigurationManager.AppSettings.Get(key) ?? defaultValue;
1113
}
14+
public static T Get<T>(string key)
15+
{
16+
var value = ConfigurationManager.AppSettings.Get(key);
17+
if (string.IsNullOrWhiteSpace(value))
18+
{
19+
return default;
20+
}
21+
22+
try
23+
{
24+
return JsonConvert.DeserializeObject<T>(value);
25+
}
26+
catch
27+
{
28+
return default;
29+
}
30+
}
1231
}
1332
}
1433

1534
#else
1635

1736
using Microsoft.Extensions.Configuration;
37+
using Newtonsoft.Json;
38+
using Newtonsoft.Json.Linq;
1839
using System;
40+
using System.Linq;
1941

2042
namespace Masuit.Tools.Config
2143
{
@@ -27,14 +49,108 @@ public static class ConfigHelper
2749
/// <summary>
2850
/// 配置对象
2951
/// </summary>
30-
public static IConfiguration Configuration { get; private set; } = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory).AddJsonFile("appsettings.json", true, true).Build();
52+
private static IConfiguration Configuration { get; set; } = new ConfigurationBuilder().SetBasePath(AppContext.BaseDirectory).AddJsonFile("appsettings.json", true, true).Build();
3153

3254
public static string GetConfigOrDefault(string key, string defaultValue = "")
3355
{
3456
string config = Configuration[key];
3557
return config.IsNullOrEmpty() ? defaultValue : config;
3658
}
3759

60+
public static T Get<T>(string key)
61+
{
62+
var section = Configuration?.GetSection(key);
63+
if (section == null)
64+
{
65+
return default;
66+
}
67+
68+
if (!section.GetChildren().Any())
69+
{
70+
var value = section.Value ?? Configuration[key];
71+
if (string.IsNullOrEmpty(value))
72+
{
73+
return default;
74+
}
75+
76+
return ConvertTo<T>(value);
77+
}
78+
79+
var token = BuildToken(section);
80+
return token is null ? default : token.ToObject<T>(JsonSerializer.CreateDefault());
81+
}
82+
83+
private static T ConvertTo<T>(string value)
84+
{
85+
var targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
86+
try
87+
{
88+
if (targetType == typeof(string))
89+
{
90+
return (T)(object)value;
91+
}
92+
93+
if (targetType.IsEnum)
94+
{
95+
return (T)Enum.Parse(targetType, value, true);
96+
}
97+
98+
if (targetType == typeof(Guid))
99+
{
100+
return (T)(object)Guid.Parse(value);
101+
}
102+
103+
if (targetType == typeof(bool))
104+
{
105+
if (bool.TryParse(value, out var b)) return (T)(object)b;
106+
if (int.TryParse(value, out var bi)) return (T)(object)(bi != 0);
107+
}
108+
109+
if (targetType.IsPrimitive || targetType == typeof(decimal))
110+
{
111+
return (T)Convert.ChangeType(value, targetType);
112+
}
113+
}
114+
catch
115+
{
116+
}
117+
118+
try
119+
{
120+
return JsonConvert.DeserializeObject<T>(value);
121+
}
122+
catch
123+
{
124+
return default;
125+
}
126+
}
127+
128+
private static JToken BuildToken(IConfigurationSection section)
129+
{
130+
var children = section.GetChildren().ToList();
131+
if (children.Count == 0)
132+
{
133+
return section.Value != null ? JToken.FromObject(section.Value) : null;
134+
}
135+
136+
if (children.All(c => int.TryParse(c.Key, out _)))
137+
{
138+
var array = new JArray();
139+
foreach (var child in children.OrderBy(c => int.Parse(c.Key)))
140+
{
141+
array.Add(BuildToken(child));
142+
}
143+
return array;
144+
}
145+
146+
var obj = new JObject();
147+
foreach (var child in children)
148+
{
149+
obj[child.Key] = BuildToken(child);
150+
}
151+
return obj;
152+
}
153+
38154
/// <summary>
39155
/// 将配置添加到Masuit.Tools,若未调用,将自动加载默认的appsettings.json
40156
/// </summary>

Masuit.Tools.Abstractions/Validator/IsEmailAttribute.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using DnsClient;
22
using Masuit.Tools.Config;
3-
using System;
43
using System.ComponentModel.DataAnnotations;
54
using System.Linq;
65
using System.Net;
@@ -19,12 +18,12 @@ public class IsEmailAttribute : ValidationAttribute
1918
/// <summary>
2019
/// 域白名单
2120
/// </summary>
22-
private string WhiteList { get; set; }
21+
private string[] WhiteList { get; set; }
2322

2423
/// <summary>
2524
/// 域黑名单
2625
/// </summary>
27-
private string BlockList { get; set; }
26+
private string[] BlockList { get; set; }
2827

2928
/// <summary>
3029
/// 是否允许为空
@@ -49,8 +48,8 @@ public IsEmailAttribute(bool validDns = true, string customMessage = null)
4948
/// <returns></returns>
5049
public override bool IsValid(object value)
5150
{
52-
WhiteList = Regex.Replace(ConfigHelper.GetConfigOrDefault("EmailDomainWhiteList"), @"(\w)\.([a-z]+),?", @"$1\.$2!").Trim('!');
53-
BlockList = Regex.Replace(ConfigHelper.GetConfigOrDefault("EmailDomainBlockList"), @"(\w)\.([a-z]+),?", @"$1\.$2!").Trim('!');
51+
WhiteList = ConfigHelper.Get<string[]>("EmailDomainWhiteList") ?? [];
52+
BlockList = ConfigHelper.Get<string[]>("EmailDomainBlockList") ?? [];
5453
if (AllowEmpty)
5554
{
5655
switch (value)
@@ -80,12 +79,12 @@ public override bool IsValid(object value)
8079
return false;
8180
}
8281

83-
if (!string.IsNullOrEmpty(WhiteList) && WhiteList.Split('!').Any(item => Regex.IsMatch(email, item)))
82+
if (WhiteList.Any(item => Regex.IsMatch(email, item)))
8483
{
8584
return true;
8685
}
8786

88-
if (!string.IsNullOrEmpty(BlockList) && BlockList.Split(['!', ';'], StringSplitOptions.RemoveEmptyEntries).Any(item => Regex.IsMatch(email, item)))
87+
if (BlockList.Any(item => Regex.IsMatch(email, item)))
8988
{
9089
ErrorMessage = _customMessage ?? "您输入的邮箱无效,请使用真实有效的邮箱地址!";
9190
return false;
@@ -96,7 +95,7 @@ public override bool IsValid(object value)
9695
{
9796
var nslookup = new LookupClient();
9897
var records = nslookup.Query(email.Split('@')[1], QueryType.MX).Answers.MxRecords().ToList();
99-
if (!string.IsNullOrEmpty(BlockList) && records.Exists(r => BlockList.Split('!').Any(item => Regex.IsMatch(r.Exchange.Value, item))))
98+
if (records.Exists(r => BlockList.Any(item => Regex.IsMatch(r.Exchange.Value, item))))
10099
{
101100
ErrorMessage = _customMessage ?? "您输入的邮箱无效,请使用真实有效的邮箱地址!";
102101
return false;

Masuit.Tools.Excel/Masuit.Tools.Excel.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
</None>
3838
</ItemGroup>
3939
<ItemGroup>
40-
<PackageReference Include="EPPlus" Version="8.0.8" />
40+
<PackageReference Include="EPPlus" Version="8.1.0" />
4141
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
4242
</ItemGroup>
4343
<ItemGroup>
Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Configuration;
1+
using Newtonsoft.Json;
2+
using System.Configuration;
23

34
namespace Masuit.Tools.Config
45
{
@@ -8,5 +9,23 @@ public static string GetConfigOrDefault(string key, string defaultValue = "")
89
{
910
return ConfigurationManager.AppSettings.Get(key) ?? defaultValue;
1011
}
12+
13+
public static T Get<T>(string key)
14+
{
15+
var value = ConfigurationManager.AppSettings.Get(key);
16+
if (string.IsNullOrWhiteSpace(value))
17+
{
18+
return default;
19+
}
20+
21+
try
22+
{
23+
return JsonConvert.DeserializeObject<T>(value);
24+
}
25+
catch
26+
{
27+
return default;
28+
}
29+
}
1130
}
12-
}
31+
}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ mongodb的封装操作类独立包
9292

9393
工具库需要用到外部配置节,.NET Framework项目配置在web.config/app.config的AppSettings配置节中,.NET Core项目配置在appsettings.json中:
9494

95-
1. EmailDomainWhiteList,邮箱校验需要用到的白名单域名,英文逗号分隔,每个元素支持正则表达式,若未配置,则不启用邮箱校验白名单,示例: `"^\\w{1,5}@qq.com,^\\w{1,5}@163.com,^\\w{1,5}@gmail.com,^\\w{1,5}@outlook.com"`
96-
2. EmailDomainBlockList,邮箱校验需要用到的黑名单域名,英文逗号分隔,每个元素支持正则表达式,且黑名单优先级高于白名单,若未配置,则不启用邮箱校验黑白名单
95+
1. EmailDomainWhiteList,邮箱校验需要用到的白名单域名正则表达式,数组形式,每个元素支持正则表达式,若未配置,则不启用邮箱校验白名单,示例: `["^\\w{1,5}@qq.com","^\\w{1,5}@163.com","^\\w{1,5}@gmail.com","^\\w{1,5}@outlook.com"]`
96+
2. EmailDomainBlockList,邮箱校验需要用到的黑名单域名正则表达式,数组形式,每个元素支持正则表达式,且黑名单优先级高于白名单,若未配置,则不启用邮箱校验黑白名单
9797

9898
```csharp
9999
public Startup(IConfiguration configuration)
@@ -145,7 +145,7 @@ https://replit.com/@ldqk/MasuitToolsDemo?v=1#main.cs
145145
### 1. 检验字符串是否是Email、手机号、URL、IP地址、身份证号等
146146

147147
```csharp
148-
var (isMatch, match) = "337845818@qq.com".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",
148+
var (isMatch, match) = "337845818@qq.com".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"]
149149
bool isInetAddress = "114.114.114.114".MatchInetAddress(); // 匹配IP地址
150150
bool isUrl = "http://masuit.org/20/history".MatchUrl(); // 匹配url
151151
bool isPhoneNumber = "15205201520".MatchPhoneNumber(); // 匹配手机号

Test/Masuit.Tools.Abstractions.Test/Masuit.Tools.Abstractions.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
1717
<PackageReference Include="Moq" Version="4.20.72" />
1818
<PackageReference Include="xunit" Version="2.9.3" />
19-
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
19+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
2020
<PrivateAssets>all</PrivateAssets>
2121
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2222
</PackageReference>

Test/Masuit.Tools.Core.Test/Masuit.Tools.Core.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.8" />
1515
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
1616
<PackageReference Include="xunit" Version="2.9.3" />
17-
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3">
17+
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4">
1818
<PrivateAssets>all</PrivateAssets>
1919
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
2020
</PackageReference>

Test/Masuit.Tools.Test/Masuit.Tools.Test.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
<Version>2.0.3</Version>
110110
</PackageReference>
111111
<PackageReference Include="xunit.analyzers">
112-
<Version>1.23.0</Version>
112+
<Version>1.24.0</Version>
113113
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
114114
<PrivateAssets>all</PrivateAssets>
115115
</PackageReference>

0 commit comments

Comments
 (0)