类别:源码工具

日期:2021-02-01 浏览:2065 评论: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,由此也可以说明大伙也挺喜欢这个工具组件的。

项目趋势

本站开源项目——.NET万能框架:Masuit.Tools_2.4.1.4版本发布

更新日志

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<stringbool>> where1 = s => s.StartsWith("a");
Expression<Func<stringbool>> where2 = s => s.Length > 10;
Func<stringbool> func = where1.And(where2).Compile();
bool b=func("abcd12345678");//true
1
2
3
4
Expression<Func<stringbool>> where1 = s => s.StartsWith("a");
Expression<Func<stringbool>> where2 = s => s.Length > 10;
Func<stringbool> 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 =>
{
      req.Referer = "https://masuit.com";
      req.Headers.Add("Origin""https://baidu.com");
});
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 { getset; }
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 { getset; }
    [IsPhone]
    public string PhoneNumber { getset; }
    [IsIPAddress]
    public string IP { getset; }
    [MinValue(0, ErrorMessage = "年龄最小为0岁"), MaxValue(100, ErrorMessage = "年龄最大100岁")]
    public int Age { getset; }
    [ComplexPassword]//密码复杂度校验
    public string Password { getset; }
}

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();// 判断是否是私有地址
bool isExternalAddress = "http://baidu.com".IsExternalAddress();// 判断是否是外网的URL
 
//以下需要配置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<intstring> 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<stringint>()
{
    ["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/


本文标题:.NET万能框架:Masuit.Tools
本文链接:https://vtzw.com/post/573.html
作者授权:除特别说明外,本文由 零一 原创编译并授权 零一的世界 刊载发布。
版权声明:本文不使用任何协议授权,您可以任何形式自由转载或使用。
 您阅读本篇文章共花了: 

 可能感兴趣的文章

评论区

发表评论 / 取消回复

必填

选填

选填

◎欢迎讨论,请在这里发表您的看法及观点。