Explorar o código

增加stream扩展方法;
邮箱校验增强

懒得勤快 %!s(int64=4) %!d(string=hai) anos
pai
achega
c5a2d8938a

+ 276 - 5
Masuit.Tools.Abstractions/Extensions/BaseType/StreamExtensions.cs

@@ -1,10 +1,12 @@
-using System.IO;
-#if NET5_0
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+#if NET5_0_OR_GREATER
 using System;
 using System.Buffers;
 using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
 #endif
 
 namespace Masuit.Tools
@@ -38,7 +40,276 @@ namespace Masuit.Tools
             return bytes;
         }
 
-#if NET5_0
+        /// <summary>
+        /// 读取所有行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static List<string> ReadAllLines(this StreamReader stream, bool closeAfter = true)
+        {
+            var stringList = new List<string>();
+            string str;
+            while ((str = stream.ReadLine()) != null)
+            {
+                stringList.Add(str);
+            }
+
+            if (closeAfter)
+            {
+                stream.Close();
+                stream.Dispose();
+            }
+            return stringList;
+        }
+
+        /// <summary>
+        /// 读取所有行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static List<string> ReadAllLines(this FileStream stream, Encoding encoding, bool closeAfter = true)
+        {
+            var stringList = new List<string>();
+            string str;
+            var sr = new StreamReader(stream, encoding);
+            while ((str = sr.ReadLine()) != null)
+            {
+                stringList.Add(str);
+            }
+
+            if (closeAfter)
+            {
+                sr.Close();
+                sr.Dispose();
+                stream.Close();
+                stream.Dispose();
+            }
+
+            return stringList;
+        }
+
+        /// <summary>
+        /// 读取所有文本
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static string ReadAllText(this FileStream stream, Encoding encoding, bool closeAfter = true)
+        {
+            var sr = new StreamReader(stream, encoding);
+            var text = sr.ReadToEnd();
+            if (closeAfter)
+            {
+                sr.Close();
+                sr.Dispose();
+                stream.Close();
+                stream.Dispose();
+            }
+
+            return text;
+        }
+
+        /// <summary>
+        /// 写入所有文本
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="content"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static void WriteAllText(this FileStream stream, string content, Encoding encoding, bool closeAfter = true)
+        {
+            var sw = new StreamWriter(stream, encoding);
+            sw.Write(content);
+            if (closeAfter)
+            {
+                sw.Close();
+                sw.Dispose();
+                stream.Close();
+                stream.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// 写入所有文本行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="lines"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static void WriteAllLines(this FileStream stream, IEnumerable<string> lines, Encoding encoding, bool closeAfter = true)
+        {
+            var sw = new StreamWriter(stream, encoding);
+            foreach (var line in lines)
+            {
+                sw.WriteLine(line);
+            }
+
+            sw.Flush();
+            if (closeAfter)
+            {
+                sw.Close();
+                sw.Dispose();
+                stream.Close();
+                stream.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// 共享读写打开文件
+        /// </summary>
+        /// <param name="file"></param>
+        /// <returns></returns>
+        public static FileStream ShareReadWrite(this FileInfo file)
+        {
+            return file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
+        }
+
+        /// <summary>
+        /// 读取所有行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static async Task<List<string>> ReadAllLinesAsync(this StreamReader stream, bool closeAfter = true)
+        {
+            var stringList = new List<string>();
+            string str;
+            while ((str = await stream.ReadLineAsync().ConfigureAwait(false)) != null)
+            {
+                stringList.Add(str);
+            }
+
+            if (closeAfter)
+            {
+                stream.Close();
+                stream.Dispose();
+            }
+            return stringList;
+        }
+
+        /// <summary>
+        /// 读取所有行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static async Task<List<string>> ReadAllLinesAsync(this FileStream stream, Encoding encoding, bool closeAfter = true)
+        {
+            var stringList = new List<string>();
+            string str;
+            var sr = new StreamReader(stream, encoding);
+            while ((str = await sr.ReadLineAsync().ConfigureAwait(false)) != null)
+            {
+                stringList.Add(str);
+            }
+
+            if (closeAfter)
+            {
+                sr.Close();
+                sr.Dispose();
+                stream.Close();
+#if NET5_0_OR_GREATER
+                await stream.DisposeAsync().ConfigureAwait(false); 
+#else
+                stream.Dispose();
+#endif
+            }
+
+            return stringList;
+        }
+
+        /// <summary>
+        /// 读取所有文本
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static async Task<string> ReadAllTextAsync(this FileStream stream, Encoding encoding, bool closeAfter = true)
+        {
+            var sr = new StreamReader(stream, encoding);
+            var text = await sr.ReadToEndAsync().ConfigureAwait(false);
+            if (closeAfter)
+            {
+                sr.Close();
+                sr.Dispose();
+                stream.Close();
+#if NET5_0_OR_GREATER
+                await stream.DisposeAsync().ConfigureAwait(false); 
+#else
+                stream.Dispose();
+#endif
+            }
+
+            return text;
+        }
+
+        /// <summary>
+        /// 写入所有文本
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="content"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static async Task WriteAllTextAsync(this FileStream stream, string content, Encoding encoding, bool closeAfter = true)
+        {
+            var sw = new StreamWriter(stream, encoding);
+            await sw.WriteAsync(content).ConfigureAwait(false);
+            await sw.FlushAsync().ConfigureAwait(false);
+            if (closeAfter)
+            {
+                sw.Close();
+                stream.Close();
+#if NET5_0_OR_GREATER
+                await sw.DisposeAsync().ConfigureAwait(false);
+                await stream.DisposeAsync().ConfigureAwait(false); 
+#else
+                sw.Dispose();
+                stream.Dispose();
+#endif
+            }
+        }
+
+        /// <summary>
+        /// 写入所有文本行
+        /// </summary>
+        /// <param name="stream"></param>
+        /// <param name="lines"></param>
+        /// <param name="encoding"></param>
+        /// <param name="closeAfter">读取完毕后关闭流</param>
+        /// <returns></returns>
+        public static async Task WriteAllLinesAsync(this FileStream stream, IEnumerable<string> lines, Encoding encoding, bool closeAfter = true)
+        {
+            var sw = new StreamWriter(stream, encoding);
+            foreach (var line in lines)
+            {
+                await sw.WriteLineAsync(line).ConfigureAwait(false);
+            }
+
+            await sw.FlushAsync().ConfigureAwait(false);
+            if (closeAfter)
+            {
+                sw.Close();
+                stream.Close();
+#if NET5_0_OR_GREATER
+                await sw.DisposeAsync().ConfigureAwait(false);
+                await stream.DisposeAsync().ConfigureAwait(false); 
+#else
+                sw.Dispose();
+                stream.Dispose();
+#endif
+            }
+        }
+
+#if NET5_0_OR_GREATER
         /// <summary>
         /// 
         /// </summary>

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

@@ -4,7 +4,7 @@
     <LangVersion>latest</LangVersion>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <CodeAnalysisRuleSet />
-    <Version>2.4.4.1</Version>
+    <Version>2.4.4.2</Version>
     <Authors>懒得勤快</Authors>
     <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
     <Copyright>懒得勤快,长空X</Copyright>
@@ -17,9 +17,9 @@
     <RepositoryType>Github</RepositoryType>
     <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
     <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
-    <FileVersion>2.4.4.1</FileVersion>
+    <FileVersion>2.4.4.2</FileVersion>
     <Company>masuit.com</Company>
-    <AssemblyVersion>2.4.4.1</AssemblyVersion>
+    <AssemblyVersion>2.4.4.2</AssemblyVersion>
     <PackageLicenseUrl>https://github.com/ldqk/Masuit.Tools/blob/master/LICENSE</PackageLicenseUrl>
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>
@@ -42,13 +42,13 @@
 
   <ItemGroup>
     <PackageReference Include="DnsClient" Version="1.5.0" />
-    <PackageReference Include="HtmlSanitizer" Version="6.0.437" />
+    <PackageReference Include="HtmlSanitizer" Version="6.0.441" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
     <PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
     <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
     <PackageReference Include="System.Management" Version="4.7.0" />
     <PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
-        <PackageReference Include="SharpCompress" Version="0.28.3" />
+        <PackageReference Include="SharpCompress" Version="0.29.0" />
   </ItemGroup>
 
   <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">

+ 28 - 4
Masuit.Tools.Abstractions/Validator/IsEmailAttribute.cs

@@ -1,6 +1,8 @@
-using Masuit.Tools.Config;
+using DnsClient;
+using Masuit.Tools.Config;
 using System.ComponentModel.DataAnnotations;
 using System.Linq;
+using System.Net;
 using System.Text.RegularExpressions;
 
 namespace Masuit.Tools.Core.Validator
@@ -23,7 +25,7 @@ namespace Masuit.Tools.Core.Validator
         private string BlockList { get; }
 
         /// <summary>
-        /// 可在配置文件AppSetting节中添加EmailDomainWhiteList配置邮箱域名白名单,EmailDomainBlockList配置邮箱域名黑名单,逗号分隔,每个单独的元素支持正则表达式
+        /// 可在配置文件AppSetting节中添加EmailDomainWhiteList配置邮箱域名白名单,EmailDomainBlockList配置邮箱域名黑名单,英文分号(;)或感叹号(!)或逗号(,)分隔,每个单独的元素支持正则表达式
         /// </summary>
         /// <param name="valid">是否检查邮箱的有效性</param>
         public IsEmailAttribute(bool valid = true)
@@ -59,7 +61,7 @@ namespace Masuit.Tools.Core.Validator
                 return false;
             }
 
-            if (!string.IsNullOrEmpty(BlockList) && BlockList.Split('!').Any(item => Regex.IsMatch(email, item)))
+            if (!string.IsNullOrEmpty(BlockList) && BlockList.Split('!', ';').Any(item => Regex.IsMatch(email, item)))
             {
                 ErrorMessage = "您输入的邮箱无效,请使用真实有效的邮箱地址!";
                 return false;
@@ -70,7 +72,29 @@ namespace Masuit.Tools.Core.Validator
                 return true;
             }
 
-            if (email.MatchEmail(_valid).isMatch)
+            var isMatch = email.MatchEmail().isMatch;
+            if (isMatch && _valid)
+            {
+                var nslookup = new LookupClient();
+                var records = nslookup.Query(email.Split('@')[1], QueryType.MX).Answers.MxRecords().ToList();
+                if (!string.IsNullOrEmpty(BlockList) && records.Any(r => BlockList.Split('!').Any(item => Regex.IsMatch(r.Exchange.Value, item))))
+                {
+                    ErrorMessage = "您输入的邮箱无效,请使用真实有效的邮箱地址!";
+                    return false;
+                }
+
+                var task = records.SelectAsync(r => Dns.GetHostAddressesAsync(r.Exchange.Value).ContinueWith(t =>
+                {
+                    if (t.IsCanceled || t.IsFaulted)
+                    {
+                        return new[] { IPAddress.Loopback };
+                    }
+
+                    return t.Result;
+                }));
+                isMatch = task.Result.SelectMany(a => a).Any(ip => !ip.IsPrivateIP());
+            }
+            if (isMatch)
             {
                 return true;
             }

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

@@ -18,10 +18,10 @@ github:https://github.com/ldqk/Masuit.Tools
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <RepositoryType>Github</RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>2.4.4.1</Version>
-        <FileVersion>2.4.4.1</FileVersion>
+        <Version>2.4.4.2</Version>
+        <FileVersion>2.4.4.2</FileVersion>
         <Company>masuit.com</Company>
-        <AssemblyVersion>2.4.4.1</AssemblyVersion>
+        <AssemblyVersion>2.4.4.2</AssemblyVersion>
         <Authors>懒得勤快X</Authors>
         <RepositoryUrl>https://github.com/ldqk/Masuit.Tools</RepositoryUrl>
         <EmbedUntrackedSources>true</EmbedUntrackedSources>
@@ -54,7 +54,7 @@ github:https://github.com/ldqk/Masuit.Tools
         <PackageReference Include="System.Drawing.Common" Version="5.0.0" />
     </ItemGroup>
     <ItemGroup Condition=" '$(TargetFramework)' == 'net5'">
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.9" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.10" />
         <PackageReference Include="System.Diagnostics.PerformanceCounter" Version="5.0.1" />
         <PackageReference Include="System.Drawing.Common" Version="5.0.2" />
     </ItemGroup>

BIN=BIN
Masuit.Tools.Net45/Properties/AssemblyInfo.cs


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

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

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

@@ -160,7 +160,7 @@
       <Version>1.5.0</Version>
     </PackageReference>
     <PackageReference Include="HtmlSanitizer">
-      <Version>6.0.437</Version>
+      <Version>6.0.441</Version>
     </PackageReference>
     <PackageReference Include="Microsoft.AspNet.Mvc">
       <Version>5.2.7</Version>
@@ -169,7 +169,7 @@
       <Version>13.0.1</Version>
     </PackageReference>
     <PackageReference Include="SharpCompress">
-      <Version>0.28.3</Version>
+      <Version>0.29.0</Version>
     </PackageReference>
     <PackageReference Include="StackExchange.Redis">
       <Version>2.2.62</Version>

BIN=BIN
Masuit.Tools/Properties/AssemblyInfo.cs


+ 1 - 1
Masuit.Tools/package.nuspec

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

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

@@ -9,7 +9,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.9" />
+    <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.10" />
     <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
     <PackageReference Include="xunit" Version="2.4.1" />