类别:源码工具
日期:2021-02-01 浏览:2309 评论:0
项目起因
这可以说是博主从入坑编程多年来的代码积累吧,所以把一些编程中常用的一些代码进行了封装,在后续的任何开发当中使用上它,避免重复地去造一些轮子,把重心转移到项目的推进,几乎可以做任何的事情,反正现在项目中没了它,我写逻辑代码还真有点困难,由于C#语言有个其他语言不可替代的特性:扩展方法,所以项目的实现90%以上都是通过扩展方法实现的,方便直接调用。
项目简介
项目基于.NET 4.5构建,语法版本C#6.0,包含日常编程多数的常用封装,可以说是一个万能框架,能够用于任何基于.NET平台的项目当中。
功能主要覆盖:
数据库操作:内存表操作、关系实体映射等;
日期时间常用操作:农历操作、时间戳操作,时分秒转换等;
文件操作:大文件操作、文件压缩与解压、ini配置文件操作;
硬件操作:获取电脑各个硬件的性能指标;
Html操作:利用C#对html字符串进行“dom”操作,html的XSS净化、html标签操作;
日志组件:高并发可用的高性能日志记录;
多媒体文件操作:图片的各种处理;
网络操作:获取线程内唯一对象、Session和Cookie的扩展、获取IP地址详细信息、缓存操作;
Nosql:仅封装了Redis的常用操作,mongodb的操作类客户端独立分开了;
反射操作:各种对对象的字段属性和方法的快捷方式;
加密安全:对字符串进行的扩展,包含AES、DES、MD5、hash、SHA1、加盐等;
字符串扩展:包含验证码生成、各种与字符串相关的扩展;
Win32API:包含于Windows系统接口相关的操作封装;
全局扩展:包含字符串扩展,类型转换,委托、循环操作、异步操作、正则等。
编译环境:Windows10 x64 + VisualStudio2019 + .NET Framework 4.6.1 + .NET Core 3.1
项目源代码托管于github,程序包发布于nuget,截止2020年9月,已有80000余次下载,全网收藏总数已超过1800star,由此也可以说明大伙也挺喜欢这个工具组件的。
项目趋势
更新日志
1. 改进进制转换
2. 获取ip信息优化
3. 修正图片类会自动释放的bug
4. 类型转换和linq扩展增加默认可选参数
5. .NET Framework版本的引用包优化
GetStart
安装程序包
.NET Framework ≥4.6.1
1 | PM> Install-Package Masuit.Tools.Net |
.NET Core 2.x/3.x
1 | PM> Install-Package Masuit.Tools.Core |
为工具库注册配置
工具库需要用到外部配置节:
1. EmailDomainWhiteList,邮箱校验需要用到的白名单域名,英文逗号分隔,每个元素支持正则表达式,若未配置,则不启用邮箱校验白名单
2. EmailDomainBlockList,邮箱校验需要用到的黑名单域名,英文逗号分隔,每个元素支持正则表达式,且黑名单优先级高于白名单,若未配置,则不启用邮箱校验黑白名单
3. BaiduAK,获取IP/地理位置相关百度云APIKey,若未配置,则无法调用GetIPLocation以及GetPhysicalAddress相关方法
1 2 3 4 | public Startup(IConfiguration configuration) { configuration.AddToMasuitTools(); // 若未调用,则默认自动尝试加载appsettings.json } |
1.检验字符串是否是Email、手机号、URL、IP地址、身份证号
bool isEmail="3444764617@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", bool isInetAddress = "114.114.114.114".MatchInetAddress(); bool isUrl = "http://masuit.com".MatchUrl(); bool isPhoneNumber = "15205201520".MatchPhoneNumber(); bool isIdentifyCard = "312000199502230660".MatchIdentifyCard();// 校验中国大陆身份证号 bool isCNPatentNumber = "200410018477.9".MatchCNPatentNumber(); // 校验中国专利申请号或专利号,是否带校验位,校验位前是否带“.”,都可以校验,待校验的号码前不要带CN、ZL字样的前缀
2.硬件监测
float load = SystemInfo.CpuLoad;// 获取CPU占用率 long physicalMemory = SystemInfo.PhysicalMemory;// 获取物理内存总数 long memoryAvailable = SystemInfo.MemoryAvailable;// 获取物理内存可用率 double freePhysicalMemory = SystemInfo.GetFreePhysicalMemory();// 获取可用物理内存 Dictionary<string, string> diskFree = SystemInfo.DiskFree();// 获取磁盘每个分区可用空间 Dictionary<string, string> diskTotalSpace = SystemInfo.DiskTotalSpace();// 获取磁盘每个分区总大小 Dictionary<string, double> diskUsage = SystemInfo.DiskUsage();// 获取磁盘每个分区使用率 double temperature = SystemInfo.GetCPUTemperature();// 获取CPU温度 int cpuCount = SystemInfo.GetCpuCount();// 获取CPU核心数 IList<string> ipAddress = SystemInfo.GetIPAddress();// 获取本机所有IP地址 string localUsedIp = SystemInfo.GetLocalUsedIP();// 获取本机当前正在使用的IP地址 IList<string> macAddress = SystemInfo.GetMacAddress();// 获取本机所有网卡mac地址 string osVersion = SystemInfo.GetOsVersion();// 获取操作系统版本 RamInfo ramInfo = SystemInfo.GetRamInfo();// 获取内存信息
3.大文件操作
FileStream fs = new FileStream(@"D:\boot.vmdk", FileMode.OpenOrCreate, FileAccess.ReadWrite); { //fs.CopyToFile(@"D:\1.bak");//同步复制大文件 fs.CopyToFileAsync(@"D:\1.bak");//异步复制大文件 string md5 = fs.GetFileMD5Async().Result;//异步获取文件的MD5 }
4.html的防XSS处理:
string html = @"<link href='/Content/font-awesome/css' rel='stylesheet'/> <!--[if IE 7]> <link href='/Content/font-awesome-ie7.min.css' rel='stylesheet'/> <![endif]--> <script src='/Scripts/modernizr'></script> <div id='searchBox' role='search'> <form action='/packages' method='get'> <span class='user-actions'><a href='/users/account/LogOff'>退出</a></span> <input name='q' id='searchBoxInput'/> <input id='searchBoxSubmit' type='submit' value='Submit' /> </form> </div>"; string s = html.HtmlSantinizerStandard();//清理后:<div><span><a href="/users/account/LogOff">退出</a></span></div>
5.整理操作系统的内存:
1 | Windows.ClearMemorySilent(); |
6.任意进制转换
1 2 3 4 5 6 | NumberFormater nf = new NumberFormater(36); //内置2-62进制的转换 //NumberFormater nf = new NumberFormater("0123456789abcdefghijklmnopqrstuvwxyz");// 自定义进制字符,可用于生成验证码 string s36 = nf.ToString(12345678); long num = nf.FromString( "7clzi" ); Console.WriteLine( "12345678的36进制是:" + s36); // 7clzi Console.WriteLine( "36进制的7clzi是:" + num); // 12345678 |
1 2 3 | //扩展方法形式调用 var bin=12345678.ToBinary(36); //7clzi var num= "7clzi" .FromBinary(36); //12345678 |
1 2 3 4 5 | //超大数字的进制转换 var num = "E6186159D38CD50E0463A55E596336BD" .FromBinaryBig(16); Console.WriteLine(num); // 十进制:305849028665645097422198928560410015421 Console.WriteLine(num.ToBinary(64)); // 64进制:3C665pQUPl3whzFlVpoPqZ,22位长度 Console.WriteLine(num.ToBinary(36)); // 36进制:dmed4dkd5bhcg4qdktklun0zh,25位长度 |
7.纳秒级性能计时器
1 2 3 4 5 6 7 | HiPerfTimer timer = HiPerfTimer.StartNew(); for ( int i = 0; i < 100000; i++) { //todo } timer.Stop(); Console.WriteLine( "执行for循环100000次耗时" +timer.Duration+ "s" ); |
1 2 3 4 5 6 7 8 | double time = HiPerfTimer.Execute(() => { for ( int i = 0; i < 100000; i++) { //todo } }); Console.WriteLine( "执行for循环100000次耗时" +time+ "s" ); |
8.单机产生唯一有序的短id
1 | var token=Stopwatch.GetTimestamp().ToBinary(36); |
1 2 3 4 5 6 7 8 9 10 | var set = new HashSet< string >(); double time = HiPerfTimer.Execute(() => { for ( int i = 0; i < 1000000; i++) { set .Add(Stopwatch.GetTimestamp().ToBinary(36)); } }); Console.WriteLine( set .Count==1000000); //True Console.WriteLine( "产生100w个id耗时" +time+ "s" ); //1.6639039s |
9.产生分布式唯一有序短id
1 2 3 | var sf = SnowFlake.GetInstance(); string token = sf.GetUniqueId(); // rcofqodori0w string shortId = sf.GetUniqueShortId(8); // qodw9728 |
1 2 3 4 5 6 7 8 9 10 | var set = new HashSet< string >(); double time = HiPerfTimer.Execute(() => { for ( int i = 0; i < 1000000; i++) { set .Add(SnowFlake.GetInstance().GetUniqueId()); } }); Console.WriteLine( set .Count == 1000000); //True Console.WriteLine( "产生100w个id耗时" + time + "s" ); //2.6891495s |
10.农历转换
1 2 3 4 5 6 7 | ChineseCalendar.CustomHolidays.Add(DateTime.Parse( "2018-12-31" ), "元旦节" ); //自定义节假日 ChineseCalendar today = new ChineseCalendar(DateTime.Parse( "2018-12-31" )); Console.WriteLine(today.ChineseDateString); // 二零一八年十一月廿五 Console.WriteLine(today.AnimalString); // 生肖:狗 Console.WriteLine(today.GanZhiDateString); // 干支:戊戌年甲子月丁酉日 Console.WriteLine(today.DateHoliday); // 获取按公历计算的节假日 ... |
11.Linq表达式树扩展
1 2 3 4 | Expression<Func< string , bool >> where1 = s => s.StartsWith( "a" ); Expression<Func< string , bool >> where2 = s => s.Length > 10; Func< string , bool > func = where1.And(where2).Compile(); bool b=func( "abcd12345678" ); //true |
1 2 3 4 | Expression<Func< string , bool >> where1 = s => s.StartsWith( "a" ); Expression<Func< string , bool >> where2 = s => s.Length > 10; Func< string , bool > func = where1.Or(where2).Compile(); bool b=func( "abc" ); // true |
12.模版引擎
1 2 3 | var tmp = new Template( "{{name}},你好!" ); tmp.Set( "name" , "万金油" ); string s = tmp.Render(); //万金油,你好! |
1 2 | var tmp = new Template( "{{one}},{{two}},{{three}}" ); string s = tmp.Set( "one" , "1" ).Set( "two" , "2" ).Set( "three" , "3" ).Render(); // 1,2,3 |
1 2 3 | var tmp = new Template( "{{name}},{{greet}}!" ); tmp.Set( "name" , "万金油" ); string s = tmp.Render(); // throw 模版变量{{greet}}未被使用 |
13.List转Datatable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var list = new List<MyClass>() { new MyClass() { Name = "张三" , Age = 22 }, new MyClass() { Name = "李四" , Age = 21 }, new MyClass() { Name = "王五" , Age = 28 } }; var table = list.Select(c => new {姓名=c.Name,年龄=c.Age}).ToList().ToDataTable(); // 将自动填充列姓名和年龄 |
14.文件压缩解压
.NET Framework
1 2 3 4 5 | MemoryStream ms = SevenZipCompressor.ZipStream( new List< string >() { @"D:\1.txt" , }); //压缩成内存流 |
1 2 3 4 5 6 7 8 | SevenZipCompressor.Zip( new List< string >() { @"D:\1.txt" , }, zip); //压缩成zip SevenZipCompressor.UnRar( @"D:\Download\test.rar" , @"D:\Download\" ); //解压rar SevenZipCompressor.Decompress( @"D:\Download\test.tar" , @"D:\Download\" ); //自动识别解压压缩包 SevenZipCompressor.Decompress( @"D:\Download\test.7z" , @"D:\Download\" ); |
ASP.NET Core
Startup.cs注册组件
1 | services.AddSevenZipCompressor(); |
构造函数注入ISevenZipCompressor
1 2 3 4 5 | private readonly ISevenZipCompressor _sevenZipCompressor; public Test(ISevenZipCompressor sevenZipCompressor) { _sevenZipCompressor = sevenZipCompressor; } |
使用方式同.NET Framework版本
15.日志组件
1 2 3 4 5 6 7 | LogManager.LogDirectory=AppDomain.CurrentDomain.BaseDirectory+ "/logs" ; LogManager.Event+=info => { //todo:注册一些事件操作 }; LogManager.Info( "记录一次消息" ); LogManager.Error( new Exception( "异常消息" )); |
16.FTP客户端
1 2 3 4 5 6 7 8 9 10 | FtpClient ftpClient = FtpClient.GetAnonymousClient( "192.168.2.2" ); //创建一个匿名访问的客户端 //FtpClient ftpClient = FtpClient.GetClient("192.168.2.3","admin","123456");// 创建一个带用户名密码的客户端 ftpClient.Delete( "/1.txt" ); // 删除文件 ftpClient.Download( "/test/2.txt" , "D:\\test\\2.txt" ); // 下载文件 ftpClient.UploadFile( "/test/22.txt" , "D:\\test\\22.txt" ,(sum, progress) => { Console.WriteLine( "已上传:" +progress*1.0/sum); }); //上传文件并检测进度 List< string > files = ftpClient.GetFiles( "/" ); //列出ftp服务端文件列表 ... |
17.多线程后台下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var mtd = new MultiThreadDownloader( "https://attachments-cdn.shimo.im/yXwC4kphjVQu06rH/KeyShot_Pro_7.3.37.7z" ,Environment.GetEnvironmentVariable( "temp" ), "E:\\Downloads\\KeyShot_Pro_7.3.37.7z" ,8); mtd.Configure(req => { }); mtd.TotalProgressChanged+=(sender, e) => { var downloader = sender as MultiThreadDownloader; Console.WriteLine( "下载进度:" +downloader.TotalProgress+ "%" ); Console.WriteLine( "下载速度:" +downloader.TotalSpeedInBytes/1024/1024+ "MBps" ); }; mtd.FileMergeProgressChanged+=(sender, e) => { Console.WriteLine( "下载完成" ); }; mtd.Start(); //开始下载 //mtd.Pause(); // 暂停下载 //mtd.Resume(); // 继续下载 |
18.Socket客户端操作类
1 2 3 4 5 6 | var tcpClient = new TcpClient(AddressFamily.InterNetwork); Socket socket = tcpClient.ConnectSocket(IPAddress.Any,5000); socket.SendFile( "D:\\test\\1.txt" , false ,i => { Console.WriteLine( "已发送" +i+ "%" ); }); |
19.RedisHelper
.Net Framework:
1 2 3 4 5 6 7 8 9 10 11 12 | RedisHelper redisHelper = RedisHelper.GetInstance(); // 获取新实例并指定连接第0个数据库 //RedisHelper redisHelper = RedisHelper.GetInstance(2);// 获取新实例并指定连接第2个数据库 //RedisHelper redisHelper = RedisHelper.GetInstance("192.168.3.150:6379");// 获取新实例并指定连接第0个数据库 //RedisHelper redisHelper = RedisHelper.GetInstance("192.168.3.150:6379",2);// 获取新实例并指定连接第2个数据库 //RedisHelper redisHelper = RedisHelper.GetSingleInstance();// 获取单例实例并指定连接第2个数据库 //RedisHelper redisHelper = RedisHelper.GetSingleInstance(2);// 获取单例实例并指定连接第2个数据库 //RedisHelper redisHelper = RedisHelper.GetSingleInstance("192.168.3.150:6379");// 获取单例实例并指定连接第0个数据库 //RedisHelper redisHelper = RedisHelper.GetSingleInstance("192.168.3.150:6379",2);// 获取单例实例并指定连接第2个数据库 redisHelper.SetString( "key" , "value" ); string value = redisHelper.GetString( "key" ); redisHelper.ListLeftPush( "list" , "value" ); List< string > list = redisHelper.ListRange< string >( "list" ); |
Asp.Net Core依赖注入方式:
Startup.cs:
1 2 3 | services.AddDefaultRedisHelper( "192.168.16.145:6379,password=xilife2018,connectTimeout=1000,connectRetry=1,syncTimeout=1000" ); //注入一个默认实例 services.AddLocalRedisHelper(); // 注入本地实例 services.AddRedisHelper( "aa" , "192.168.16.145:6379,password=xilife2018,connectTimeout=1000,connectRetry=1,syncTimeout=1000" ); // 通用注入 |
Controller:
1 2 3 4 5 6 7 | public RedisHelper RedisHelper { get ; set ; } public HomeController(RedisHelperFactory redisHelperFactory) { RedisHelper=redisHelperFactory.Create( "aa" ,0); // 创建命名为aa的RedisHelper,指定数据库0 RedisHelper=redisHelperFactory.CreateDefault(0); // 创建默认的RedisHelper,指定数据库0 RedisHelper=redisHelperFactory.CreateLocal(0); // 创建连接本机的RedisHelper,指定数据库0 } |
方法调用方式和.NET Framework方式相同
20.加密解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var enc= "123456" .MDString(); // MD5加密 var enc= "123456" .MDString( "abc" ); // MD5加盐加密 var enc= "123456" .MDString2(); // MD5两次加密 var enc= "123456" .MDString2( "abc" ); // MD5两次加盐加密 var enc= "123456" .MDString3(); // MD5三次加密 var enc= "123456" .MDString3( "abc" ); // MD5三次加盐加密 string aes = "123456" .AESEncrypt(); // AES加密为密文 string s = aes.AESDecrypt(); //AES解密为明文 string aes = "123456" .AESEncrypt( "abc" ); // AES密钥加密为密文 string s = aes.AESDecrypt( "abc" ); //AES密钥解密为明文 string aes = "123456" .DesEncrypt(); // DES加密为密文 string s = aes.DesDecrypt(); //DES解密为明文 string aes = "123456" .DesEncrypt( "abcdefgh" ); // DES密钥加密为密文 string s = aes.DesDecrypt( "abcdefgh" ); //DES密钥加密为密文 RsaKey rsaKey = RsaCrypt.GenerateRsaKeys(); // 生成RSA密钥对 string encrypt = "123456" .RSAEncrypt(rsaKey.PublicKey); // 公钥加密 string s = encrypt.RSADecrypt(rsaKey.PrivateKey); // 私钥解密 string s = "123" .Crc32(); // 生成crc32摘要 string s = "123" .Crc64(); // 生成crc64摘要 |
21.Redis分布式锁
1 2 3 4 5 6 7 8 | using (RedisLock redisLock = new RedisLock( "127.0.0.1:6379" )) { if (redisLock.TryLock( "lock" , TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), out var lockObject)) // 加锁 { //todo:需要执行的原子操作 } var redisResult = redisLock.UnLock(lockObject); // 释放锁 } |
22.实体校验
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class MyClass { [IsEmail] public string Email { get ; set ; } [IsPhone] public string PhoneNumber { get ; set ; } [IsIPAddress] public string IP { get ; set ; } [MinValue(0, ErrorMessage = "年龄最小为0岁" ), MaxValue(100, ErrorMessage = "年龄最大100岁" )] public int Age { get ; set ; } [ComplexPassword] //密码复杂度校验 public string Password { get ; set ; } } |
23.HTML操作
1 2 3 4 | List< string > srcs = "html" .MatchImgSrcs().ToList(); // 获取html字符串里所有的img标签的src属性 var imgTags = "html" .MatchImgTags(); //获取html字符串里的所有的img标签 var str= "html" .RemoveHtmlTag(); // 去除html标签 ... |
24.DateTime扩展
1 2 3 4 5 6 | double milliseconds = DateTime.Now.GetTotalMilliseconds(); // 获取毫秒级时间戳 double microseconds = DateTime.Now.GetTotalMicroseconds(); // 获取微秒级时间戳 double nanoseconds = DateTime.Now.GetTotalNanoseconds(); // 获取纳秒级时间戳 double seconds = DateTime.Now.GetTotalSeconds(); // 获取秒级时间戳 double minutes = DateTime.Now.GetTotalMinutes(); // 获取分钟级时间戳 ... |
25.IP地址和URL
1 2 3 4 5 6 7 8 | bool inRange = "192.168.2.2" .IpAddressInRange( "192.168.1.1" , "192.168.3.255" ); // 判断IP地址是否在这个地址段里 bool isPrivateIp = "172.16.23.25" .IsPrivateIP(); // 判断是否是私有地址 //以下需要配置baiduAK string isp = "114.114.114.114" .GetISP(); // 获取ISP运营商信息 PhysicsAddress physicsAddress = "114.114.114.114" .GetPhysicsAddressInfo().Result; // 获取详细地理信息对象 Tuple< string , List< string >> ipAddressInfo = "114.114.114.114" .GetIPAddressInfo().Result; // 获取详细地理信息集合 |
26.元素去重
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var list = new List<MyClass>() { new MyClass() { Email = "1@1.cn" }, new MyClass() { Email = "1@1.cn" }, new MyClass() { Email = "1@1.cn" } }; List<MyClass> classes = list.DistinctBy(c => c.Email).ToList(); Console.WriteLine(classes.Count==1); //True |
27.枚举扩展
1 2 3 4 5 6 7 8 9 10 | public enum MyEnum { [Display(Name = "读" )] [Description( "读" )] Read, [Display(Name = "写" )] [Description( "写" )] Write } |
1 2 3 4 5 6 | Dictionary< int , string > dic1 = typeof (MyEnum).GetDictionary(); // 获取枚举值和字符串表示的字典映射 var dic2 = typeof (MyEnum).GetDescriptionAndValue(); // 获取字符串表示和枚举值的字典映射 string desc = MyEnum.Read.GetDescription(); // 获取Description标签 string display = MyEnum.Read.GetDisplay(); // 获取Display标签的Name属性 var value = typeof (MyEnum).GetValue( "Read" ); //获取字符串表示值对应的枚举值 string enumString = 0.ToEnumString( typeof (MyEnum)); // 获取枚举值对应的字符串表示 |
28.定长队列实现
1 2 | LimitedQueue< string > queue = new LimitedQueue< string >(32); // 声明一个容量为32个元素的定长队列 ConcurrentLimitedQueue< string > queue = new ConcurrentLimitedQueue< string >(32); // 声明一个容量为32个元素的线程安全的定长队列 |
29.反射操作
1 2 3 | MyClass myClass = new MyClass(); PropertyInfo[] properties = myClass.GetProperties(); // 获取属性列表 myClass.SetProperty( "Email" , "1@1.cn" ); //给对象设置值 |
30.获取线程内唯一对象
1 2 | CallContext<T>.SetData( "db" ,dbContext); //设置线程内唯一对象 CallContext<T>.GetData( "db" ); //获取线程内唯一对象 |
31.asp.net core 获取静态的HttpContext对象
Startup.cs
1 2 3 4 5 6 7 8 9 10 11 12 | public void ConfigureServices(IServiceCollection services) { // ... services.AddStaticHttpContext(); // ... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // ... app.UseStaticHttpContext(); // ... } |
1 2 3 4 | public async Task<IActionResult> Index() { HttpContext context = HttpContext2.Current; } |
32.邮件发送
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | new Email() { SmtpServer = "smtp.masuit.com" , // SMTP服务器 SmtpPort = 25, // SMTP服务器端口 EnableSsl = true , //使用SSL Username = "admin@masuit.com" , // 邮箱用户名 Password = "123456" , // 邮箱密码 Tos = "10000@qq.com,10001@qq.com" , //收件人 Subject = "测试邮件" , //邮件标题 Body = "你好啊" , //邮件内容 }.SendAsync(s => { Console.WriteLine(s); // 发送成功后的回调 }); // 异步发送邮件 |
33.图像的简单处理
1 2 3 4 5 6 7 8 9 10 11 12 | ImageUtilities.CompressImage( @"F:\src\1.jpg" , @"F:\dest\2.jpg" ); //无损压缩图片 "base64" .SaveDataUriAsImageFile(); // 将Base64编码转换成图片 Image image = Image.FromFile( @"D:\1.jpg" ); image.MakeThumbnail( @"D:\2.jpg" , 120, 80, ThumbnailCutMode.LockWidth); //生成缩略图 Bitmap bmp = new Bitmap( @"D:\1.jpg" ); Bitmap newBmp = bmp.BWPic(bmp.Width, bmp.Height); //转换成黑白 Bitmap newBmp = bmp.CutAndResize( new Rectangle(0, 0, 1600, 900), 160, 90); //裁剪并缩放 bmp.RevPicLR(bmp.Width, bmp.Height); //左右镜像 bmp.RevPicUD(bmp.Width, bmp.Height); //上下镜像 |
34.随机数
1 2 3 | Random rnd = new Random(); int num = rnd.StrictNext(); //产生真随机数 double gauss = rnd.NextGauss(20,5); //产生正态分布的随机数 |
35.权重筛选
1 2 3 4 5 6 7 8 9 | var data= new List<WeightedItem< string >>() { new WeightedItem< string >( "A" , 1), new WeightedItem< string >( "B" , 3), new WeightedItem< string >( "C" , 4), new WeightedItem< string >( "D" , 4), }; var item=data.WeightedItem(); //按权重选出1个元素 var list=data.WeightedItems(2); //按权重选出2个元素 |
1 2 3 4 5 6 7 8 9 | var selector = new WeightedSelector< string >( new List<WeightedItem< string >>() { new WeightedItem< string >( "A" , 1), new WeightedItem< string >( "B" , 3), new WeightedItem< string >( "C" , 4), new WeightedItem< string >( "D" , 4), }); var item = selector.Select(); //按权重选出1个元素 var list = selector.SelectMultiple(3); //按权重选出3个元素 |
36.EF Core支持AddOrUpdate方法
1 2 3 4 5 6 7 8 | /// <summary> /// 按Id添加或更新文章实体 /// </summary> public override Post SavePost(Post t) { DataContext.Set<Post>().AddOrUpdate(t => t.Id, t); return t; } |
37.敏感信息掩码
1 2 | "13123456789" .Mask(); // 131****5678 "admin@masuit.com" .MaskEmail(); // a****n@masuit.com |
38.集合扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var list = new List< string >() { "1" , "3" , "3" , "3" }; list.AddRangeIf(s => s.Length > 1, "1" , "11" ); // 将被添加元素中的长度大于1的元素添加到list list.AddRangeIfNotContains( "1" , "11" ); // 将被添加元素中不包含的元素添加到list list.RemoveWhere(s => s.Length<1); // 将集合中长度小于1的元素移除 list.InsertAfter(0, "2" ); // 在第一个元素之后插入 list.InsertAfter(s => s == "1" , "2" ); // 在元素"1"后插入 var dic = list.ToDictionarySafety(s => s); // 安全的转换成字典类型,当键重复时只添加一个键 var dic = list.ToConcurrentDictionary(s => s); // 转换成并发字典类型,当键重复时只添加一个键 var dic = list.ToDictionarySafety(s => s, s => s.GetHashCode()); // 安全的转换成字典类型,当键重复时只添加一个键 dic.AddOrUpdate( "4" , 4); // 添加或更新键值对 dic.AddOrUpdate( new Dictionary< string , int >() { [ "5" ] = 5,[ "55" ]=555 }); // 批量添加或更新键值对 dic.AddOrUpdate( "5" , 6, (s, i) => 66); // 如果是添加,则值为6,若更新则值为66 dic.AddOrUpdate( "5" , 6, 666); // 如果是添加,则值为6,若更新则值为666 dic.AsConcurrentDictionary(); // 普通字典转换成并发字典集合 var table=list.ToDataTable(); // 转换成DataTable类型 table.AddIdentityColumn(); //给DataTable增加一个自增列 table.HasRows(); // 检查DataTable 是否有数据行 table.ToList<T>(); // datatable转List var set = list.ToHashSet(s=>s.Name); // 转HashSet |
39.Mime类型
1 2 3 | var mimeMapper = new MimeMapper(); var mime = mimeMapper.GetExtensionFromMime( "image/jpeg" ); // .jpg var ext = mimeMapper.GetMimeFromExtension( ".jpg" ); // image/jpeg |
40.日期时间扩展
1 2 3 4 5 6 7 8 9 10 11 12 13 | DateTime.Now.GetTotalSeconds(); // 获取该时间相对于1970-01-01 00:00:00的秒数 DateTime.Now.GetTotalMilliseconds(); // 获取该时间相对于1970-01-01 00:00:00的毫秒数 DateTime.Now.GetTotalMicroseconds(); // 获取该时间相对于1970-01-01 00:00:00的微秒数 DateTime.Now.GetTotalNanoseconds(); // 获取该时间相对于1970-01-01 00:00:00的纳秒数 var indate=DateTime.Parse( "2020-8-3" ).In(DateTime.Parse( "2020-8-2" ),DateTime.Parse( "2020-8-4" )); //true //时间段计算工具 var range = new DateTimeRange(DateTime.Parse( "2020-8-3" ), DateTime.Parse( "2020-8-5" )); range.Union(DateTime.Parse( "2020-8-4" ), DateTime.Parse( "2020-8-6" )); //连接两个时间段,结果:2020-8-3~2020-8-6 range.In(DateTime.Parse( "2020-8-3" ), DateTime.Parse( "2020-8-6" )); //判断是否在某个时间段内,true var (intersected,range2) = range.Intersect(DateTime.Parse( "2020-8-4" ), DateTime.Parse( "2020-8-6" )); //两个时间段是否相交,(true,2020-8-3~2020-8-4) range.Contains(DateTime.Parse( "2020-8-3" ), DateTime.Parse( "2020-8-4" )); //判断是否包含某个时间段,true ... |
41.流转换
1 2 | stream.SaveAsMemoryStream(); // 任意流转换成内存流 stream.ToArray(); // 任意流转换成二进制数组 |
42.数值转换
1 2 3 | 1.2345678901.Digits8(); // 将小数截断为8位 1.23.To< int >(); // 小数转int 1.23.To<T>(); // 小数转T基本类型 |
43.简繁转换
1 2 | var str= "个体" .ToTraditional(); // 转繁体 var str= "個體" .ToSimplified(); // 转简体 |
Asp.Net MVC和Asp.Net Core的支持断点续传和多线程下载的ResumeFileResult
允许你在ASP.NET Core中通过MVC/WebAPI应用程序传输文件数据时使用断点续传以及多线程下载。
它允许提供`ETag`标题以及`Last-Modified`标题。 它还支持以下前置条件标题:`If-Match`,`If-None-Match`,`If-Modified-Since`,`If-Unmodified-Since`,`If-Range`。
支持 ASP.NET Core 2.0
从.NET Core2.0开始,ASP.NET Core内部支持断点续传。 因此只是对FileResult做了一些扩展。 只留下了“Content-Disposition” Inline的一部分。 所有代码都依赖于基础.NET类。
.NET Framework
在你的控制器中,你可以像在`FileResult`一样的方式使用它。
1 2 | using Masuit.Tools.Mvc; using Masuit.Tools.Mvc.ResumeFileResult; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | private readonly MimeMapper mimeMapper= new MimeMapper(); // 推荐使用依赖注入 public ActionResult ResumeFileResult() { var path = Server.MapPath( "~/Content/test.mp4" ); return new ResumeFileResult(path, mimeMapper.GetMimeFromPath(path), Request); } public ActionResult ResumeFile() { return this .ResumeFile( "~/Content/test.mp4" , mimeMapper.GetMimeFromPath(path), "test.mp4" ); } public ActionResult ResumePhysicalFile() { return this .ResumePhysicalFile( @"D:/test.mp4" , mimeMapper.GetMimeFromPath( @"D:/test.mp4" ), "test.mp4" ); } |
Asp.Net Core
要使用ResumeFileResults,必须在`Startup.cs`的`ConfigureServices`方法调用中配置服务:
1 | using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions; |
1 2 3 4 | public void ConfigureServices(IServiceCollection services) { services.AddResumeFileResult(); } |
然后在你的控制器中,你可以像在`FileResult`一样的方式使用它。
1 | using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | private const string EntityTag = "\"TestFile\"" ; private readonly IHostingEnvironment _hostingEnvironment; private readonly DateTimeOffset _lastModified = new DateTimeOffset(2016, 1, 1, 0, 0, 0, TimeSpan.Zero); /// <summary> /// /// </summary> /// <param name="hostingEnvironment"></param> public TestController(IHostingEnvironment hostingEnvironment) { _hostingEnvironment = hostingEnvironment; } [HttpGet( "content/{fileName}/{etag}" )] public IActionResult FileContent( bool fileName, bool etag) { string webRoot = _hostingEnvironment.WebRootPath; var content = System.IO.File.ReadAllBytes(Path.Combine(webRoot, "TestFile.txt" )); ResumeFileContentResult result = this .ResumeFile(content, "text/plain" , fileName ? "TestFile.txt" : null , etag ? EntityTag : null ); result.LastModified = _lastModified; return result; } [HttpGet( "content/{fileName}" )] public IActionResult FileContent( bool fileName) { string webRoot = _hostingEnvironment.WebRootPath; var content = System.IO.File.ReadAllBytes(Path.Combine(webRoot, "TestFile.txt" )); var result = new ResumeFileContentResult(content, "text/plain" ) { FileInlineName = "TestFile.txt" , LastModified = _lastModified }; return result; } [HttpHead( "file" )] public IActionResult FileHead() { ResumeVirtualFileResult result = this .ResumeFile( "TestFile.txt" , "text/plain" , "TestFile.txt" , EntityTag); result.LastModified = _lastModified; return result; } [HttpPut( "file" )] public IActionResult FilePut() { ResumeVirtualFileResult result = this .ResumeFile( "TestFile.txt" , "text/plain" , "TestFile.txt" , EntityTag); result.LastModified = _lastModified; return result; } [HttpGet( "stream/{fileName}/{etag}" )] public IActionResult FileStream( bool fileName, bool etag) { string webRoot = _hostingEnvironment.WebRootPath; FileStream stream = System.IO.File.OpenRead(Path.Combine(webRoot, "TestFile.txt" )); ResumeFileStreamResult result = this .ResumeFile(stream, "text/plain" , fileName ? "TestFile.txt" : null , etag ? EntityTag : null ); result.LastModified = _lastModified; return result; } [HttpGet( "stream/{fileName}" )] public IActionResult FileStream( bool fileName) { string webRoot = _hostingEnvironment.WebRootPath; FileStream stream = System.IO.File.OpenRead(Path.Combine(webRoot, "TestFile.txt" )); var result = new ResumeFileStreamResult(stream, "text/plain" ) { FileInlineName = "TestFile.txt" , LastModified = _lastModified }; return result; } [HttpGet( "physical/{fileName}/{etag}" )] public IActionResult PhysicalFile( bool fileName, bool etag) { string webRoot = _hostingEnvironment.WebRootPath; ResumePhysicalFileResult result = this .ResumePhysicalFile(Path.Combine(webRoot, "TestFile.txt" ), "text/plain" , fileName ? "TestFile.txt" : null , etag ? EntityTag : null ); result.LastModified = _lastModified; return result; } [HttpGet( "physical/{fileName}" )] public IActionResult PhysicalFile( bool fileName) { string webRoot = _hostingEnvironment.WebRootPath; var result = new ResumePhysicalFileResult(Path.Combine(webRoot, "TestFile.txt" ), "text/plain" ) { FileInlineName = "TestFile.txt" , LastModified = _lastModified }; return result; } [HttpGet( "virtual/{fileName}/{etag}" )] public IActionResult VirtualFile( bool fileName, bool etag) { ResumeVirtualFileResult result = this .ResumeFile( "TestFile.txt" , "text/plain" , fileName ? "TestFile.txt" : null , etag ? EntityTag : null ); result.LastModified = _lastModified; return result; } |
以上示例将为您的数据提供“Content-Disposition:attachment”。 当没有提供fileName时,数据将作为“Content-Disposition:inline”提供。
另外,它可以提供`ETag`和`LastModified`标题。
1 2 3 4 5 6 7 8 9 10 | [HttpGet( "virtual/{fileName}" )] public IActionResult VirtualFile( bool fileName) { var result = new ResumeVirtualFileResult( "TestFile.txt" , "text/plain" ) { FileInlineName = "TestFile.txt" , LastModified = _lastModified }; return result; } |
项目地址:
https://github.com/ldqk/Masuit.Tools
https://www.nuget.org/packages/Masuit.Tools.Core/
发表评论 / 取消回复