.NET Core 最新幫助類(Masuit.Tools)
前言
包含一些常用的操作類,大都是靜態(tài)類,加密解密,反射操作,權(quán)重隨機(jī)篩選算法,分布式短id,表達(dá)式樹,linq擴(kuò)展,文件壓縮,多線程下載和FTP客戶端,硬件信息,字符串?dāng)U展方法,日期時(shí)間擴(kuò)展操作,中國農(nóng)歷,大文件拷貝,圖像裁剪,驗(yàn)證碼,斷點(diǎn)續(xù)傳,集合擴(kuò)展、Excel導(dǎo)出等常用封裝。
諸多功能集一身,代碼量不到2MB!

項(xiàng)目開發(fā)模式:日常代碼積累+網(wǎng)絡(luò)搜集
關(guān)于本項(xiàng)目,如果你有任何不懂的地方或使用過程中遇到任何問題,可以直接提issue或私信聯(lián)系我,我會(huì)為你提供完全免費(fèi)的技術(shù)指導(dǎo)。
建議開發(fā)環(huán)境
.NET Framework版本的包因打包環(huán)境異常,無法正常發(fā)布更新,目前暫時(shí)停更~
.NET Framework ≥ 4.6.1
PM> Install-Package Masuit.Tools.Net
.NET Standard ≥ 2.1 或只想使用一些基本功能
通用項(xiàng)目推薦首選包
PM> Install-Package Masuit.Tools.Abstraction
.NET Core ≥ 2.1
.NET Core項(xiàng)目推薦首選包
PM> Install-Package Masuit.Tools.Core
.NET Framework 4.5特供版
請(qǐng)注意:這是.NET Framework 4.5的專用版本,相比4.6.1及.NET Core的版本,閹割了Redis、HTML、文件壓縮、ASP.NET擴(kuò)展、硬件監(jiān)測(cè)、Session擴(kuò)展等一些功能。如果你的項(xiàng)目版本高于4.5,請(qǐng)務(wù)必使用上述版本的包,以享受完整的功能體驗(yàn)!
PM> Install-Package Masuit.Tools.Net45
增值包
Masuit.Tools.AspNetCore
AspNetCore項(xiàng)目推薦首選包ASP.NET Core Web專用包,包含Masuit.Tools.Core的全部功能,并且增加了一些對(duì)ASP.NET Core Web功能的額外支持。
Masuit.Tools.Excel
Excel導(dǎo)入導(dǎo)出的專用獨(dú)立包
Masuit.Tools.NoSQL.MongoDBClient
mongodb的封裝操作類獨(dú)立包
為工具庫注冊(cè)配置
工具庫需要用到外部配置節(jié),.NET Framework項(xiàng)目配置在web.config/app.config的AppSettings配置節(jié)中,.NET Core項(xiàng)目配置在appsettings.json中:
1、EmailDomainWhiteList,郵箱校驗(yàn)需要用到的白名單域名,英文逗號(hào)分隔,每個(gè)元素支持正則表達(dá)式,若未配置,則不啟用郵箱校驗(yàn)白名單,示例: "^\\w{1,5}@qq.com,^\\w{1,5}@163.com,^\\w{1,5}@gmail.com,^\\w{1,5}@outlook.com"
2、EmailDomainBlockList,郵箱校驗(yàn)需要用到的黑名單域名,英文逗號(hào)分隔,每個(gè)元素支持正則表達(dá)式,且黑名單優(yōu)先級(jí)高于白名單,若未配置,則不啟用郵箱校驗(yàn)黑白名單
public Startup(IConfiguration configuration)
{
configuration.AddToMasuitTools(); // 若未調(diào)用,則默認(rèn)自動(dòng)嘗試加載appsettings.json
}
特色功能示例代碼
在線體驗(yàn)
https://replit.com/@ldqk/MasuitToolsDemo?v=1#main.cs
1、檢驗(yàn)字符串是否是Email、手機(jī)號(hào)、URL、IP地址、身份證號(hào)等
var (isMatch, match) = "[email protected]".MatchEmail(); // 可在appsetting.json中添加EmailDomainWhiteList和EmailDomainBlockList配置郵箱域名黑白名單,逗號(hào)分隔,如"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://ldqk.org/20/history".MatchUrl();
bool isPhoneNumber = "15205201520".MatchPhoneNumber();
bool isIdentifyCard = "312000199502230660".MatchIdentifyCard();// 校驗(yàn)中國大陸身份證號(hào)
bool isCNPatentNumber = "200410018477.9".MatchCNPatentNumber(); // 校驗(yàn)中國專利申請(qǐng)?zhí)柣驅(qū)@?hào),是否帶校驗(yàn)位,校驗(yàn)位前是否帶“.”,都可以校驗(yàn),待校驗(yàn)的號(hào)碼前不要帶CN、ZL字樣的前綴
2、硬件監(jiān)測(cè)(僅支持Windows,部分函數(shù)僅支持物理機(jī)模式)
float load = SystemInfo.CpuLoad;// 獲取CPU占用率
long physicalMemory = SystemInfo.PhysicalMemory;// 獲取物理內(nèi)存總數(shù)
long memoryAvailable = SystemInfo.MemoryAvailable;// 獲取物理內(nèi)存可用率
double freePhysicalMemory = SystemInfo.GetFreePhysicalMemory();// 獲取可用物理內(nèi)存
double temperature = SystemInfo.GetCPUTemperature();// 獲取CPU溫度
int cpuCount = SystemInfo.GetCpuCount();// 獲取CPU核心數(shù)
IList<string> ipAddress = SystemInfo.GetIPAddress();// 獲取本機(jī)所有IP地址
string localUsedIp = SystemInfo.GetLocalUsedIP();// 獲取本機(jī)當(dāng)前正在使用的IP地址
IList<string> macAddress = SystemInfo.GetMacAddress();// 獲取本機(jī)所有網(wǎng)卡mac地址
string osVersion = SystemInfo.GetOsVersion();// 獲取操作系統(tǒng)版本
RamInfo ramInfo = SystemInfo.GetRamInfo();// 獲取內(nèi)存信息
var cpuSN=SystemInfo.GetCpuInfo()[0].SerialNumber; // CPU序列號(hào)
var driveSN=SystemInfo.GetDiskInfo()[0].SerialNumber; // 硬盤序列號(hào)
// 快速方法
var cpuInfos = CpuInfo.Locals; // 快速獲取CPU的信息
var ramInfo = RamInfo.Local; // 快速獲取內(nèi)存的信息
var diskInfos = DiskInfo.Locals; // 快速獲取硬盤的信息
var biosInfo = BiosInfo.Local; // 快速獲取主板的信息
3、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>
4、整理Windows系統(tǒng)的內(nèi)存:
類似于各大系統(tǒng)優(yōu)化軟件的加速球功能
Windows.ClearMemorySilent();
5、任意進(jìn)制轉(zhuǎn)換
可用于生成短id,短hash,隨機(jī)字符串等操作,純數(shù)學(xué)運(yùn)算。
NumberFormater nf = new NumberFormater(36);//內(nèi)置2-62進(jìn)制的轉(zhuǎn)換
//NumberFormater nf = new NumberFormater("0123456789abcdefghijklmnopqrstuvwxyz");// 自定義進(jìn)制字符,可用于生成驗(yàn)證碼
string s36 = nf.ToString(12345678);
long num = nf.FromString("7clzi");
Console.WriteLine("12345678的36進(jìn)制是:" + s36); // 7clzi
Console.WriteLine("36進(jìn)制的7clzi是:" + num); // 12345678
var s = new NumberFormater(62).ToString(new Random().Next(100000, int.MaxValue)); //配合隨機(jī)數(shù)生成隨機(jī)字符串
//擴(kuò)展方法形式調(diào)用
var bin=12345678.ToBinary(36);//7clzi
var num="7clzi".FromBinary(36);//12345678
//超大數(shù)字的進(jìn)制轉(zhuǎn)換
var num = "e6186159d38cd50e0463a55e596336bd".FromBinaryBig(16);
Console.WriteLine(num); // 十進(jìn)制:305849028665645097422198928560410015421
Console.WriteLine(num.ToBinary(64)); // 64進(jìn)制:3C665pQUPl3whzFlVpoPqZ,22位長(zhǎng)度
Console.WriteLine(num.ToBinary(36)); // 36進(jìn)制:dmed4dkd5bhcg4qdktklun0zh,25位長(zhǎng)度
Console.WriteLine(num.ToBinary(7)); // 7進(jìn)制:2600240311641665565300424545154525131265221035,46位長(zhǎng)度
Console.WriteLine(num.ToBinary(12)); // 12進(jìn)制:5217744842749978a756b22135b16a5998a5,36位長(zhǎng)度
Console.WriteLine(num.ToBinary(41)); // 41進(jìn)制:opzeBda2aytcEeudEquuesbk,24位長(zhǎng)度
6、納秒級(jí)性能計(jì)時(shí)器
HiPerfTimer timer = HiPerfTimer.StartNew();
for (int i = 0; i < 100000; i++)
{
//todo
}
timer.Stop();
Console.WriteLine("執(zhí)行for循環(huán)100000次耗時(shí)"+timer.Duration+"s");
double time = HiPerfTimer.Execute(() =>
{
for (int i = 0; i < 100000; i++)
{
//todo
}
});
Console.WriteLine("執(zhí)行for循環(huán)100000次耗時(shí)"+time+"s");
7、產(chǎn)生分布式唯一有序短id(雪花id)
var sf = SnowFlake.GetInstance();
string token = sf.GetUniqueId();// rcofqodori0w
string shortId = sf.GetUniqueShortId(8);// qodw9728
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("產(chǎn)生100w個(gè)id耗時(shí)" + time + "s"); //2.6891495s
8、農(nóng)歷轉(zhuǎn)換
ChineseCalendar.CustomHolidays.Add(DateTime.Parse("2018-12-31"),"元旦節(jié)");//自定義節(jié)假日
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);// 獲取按公歷計(jì)算的節(jié)假日
...
9、Linq表達(dá)式樹擴(kuò)展
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)
.AndIf(!string.IsNullOrEmpty(name),s=>s==name)
.Compile(); // And和AndIf可供選擇,滿足條件再執(zhí)行And
bool b=func("abcd12345678");//true
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)
.OrIf(!string.IsNullOrEmpty(name),s=>s==name)
.Compile(); // Or和OrIf可供選擇,滿足條件再執(zhí)行Or
bool b=func("abc");// true
queryable.WhereIf(!string.IsNullOrEmpty(name),e=>e.Name==name)
.WhereIf(()=> age.HasValue,e=>e.Age>=age); // IQueryable的WhereIf擴(kuò)展函數(shù),滿足條件再執(zhí)行Where
10、模版引擎
var tmp = new Template("{{name}},你好!");
tmp.Set("name", "萬金油");
string s = tmp.Render();//萬金油,你好!
var tmp = new Template("{{one}},{{two}},{{three}}");
string s = tmp.Set("one", "1").Set("two", "2").Set("three", "3").Render();// 1,2,3
var tmp = new Template("{{name}},{{greet}}!");
tmp.Set("name", "萬金油");
string s = tmp.Render();// throw 模版變量{{greet}}未被使用
11、List轉(zhuǎn)Datatable
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}).ToDataTable();// 將自動(dòng)填充列姓名和年齡
12、文件壓縮解壓
.NET Framework
MemoryStream ms = SevenZipCompressor.ZipStream(new List<string>()
{
@"D:\1.txt",
"http://ww3.sinaimg.cn/large/87c01ec7gy1fsq6rywto2j20je0d3td0.jpg",
});//壓縮成內(nèi)存流
SevenZipCompressor.Zip(new List<string>()
{
@"D:\1.txt",
"http://ww3.sinaimg.cn/large/87c01ec7gy1fsq6rywto2j20je0d3td0.jpg",
}, zip);//壓縮成zip
SevenZipCompressor.UnRar(@"D:\Download\test.rar", @"D:\Download\");//解壓rar
SevenZipCompressor.Decompress(@"D:\Download\test.tar", @"D:\Download\");//自動(dòng)識(shí)別解壓壓縮包
SevenZipCompressor.Decompress(@"D:\Download\test.7z", @"D:\Download\");
ASP.NET Core Startup.cs
services.AddSevenZipCompressor();
構(gòu)造函數(shù)注入ISevenZipCompressor
private readonly ISevenZipCompressor _sevenZipCompressor;
public Test(ISevenZipCompressor sevenZipCompressor)
{
_sevenZipCompressor = sevenZipCompressor;
}
使用方式同.NET Framework版本
13、簡(jiǎn)易日志組件(又不是不能用.jpg)
LogManager.LogDirectory=AppDomain.CurrentDomain.BaseDirectory+"/logs";
LogManager.Event+=info =>
{
//todo:注冊(cè)一些事件操作
};
LogManager.Info("記錄一次消息");
LogManager.Error(new Exception("異常消息"));
14、FTP客戶端
FtpClient ftpClient = FtpClient.GetAnonymousClient("192.168.2.2");//創(chuàng)建一個(gè)匿名訪問的客戶端
//FtpClient ftpClient = FtpClient.GetClient("192.168.2.3","admin","123456");// 創(chuàng)建一個(gè)帶用戶名密碼的客戶端
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);
});//上傳文件并檢測(cè)進(jìn)度
List<string> files = ftpClient.GetFiles("/");//列出ftp服務(wù)端文件列表
...
15、多線程后臺(tái)下載
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("下載進(jìn)度:"+downloader.TotalProgress+"%");
Console.WriteLine("下載速度:"+downloader.TotalSpeedInBytes/1024/1024+"MBps");
};
mtd.FileMergeProgressChanged+=(sender, e) =>
{
Console.WriteLine("下載完成");
};
mtd.FileMergedComplete+=(sender,e)=>{
Console.WriteLine("文件合并完成");
};
mtd.Start();//開始下載
//mtd.Pause(); // 暫停下載
//mtd.Resume(); // 繼續(xù)下載
16、加密解密/hash
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 enc = "123456".DesEncrypt();// DES加密為密文
string s = enc.DesDecrypt(); //DES解密為明文
string enc = "123456".DesEncrypt("abcdefgh");// DES密鑰加密為密文
string s = enc.DesDecrypt("abcdefgh"); //DES密鑰解密為明文
RsaKey rsaKey = RsaCrypt.GenerateRsaKeys();// 生成RSA密鑰對(duì)
string encrypt = "123456".RSAEncrypt(rsaKey.PublicKey);// 公鑰加密
string s = encrypt.RSADecrypt(rsaKey.PrivateKey);// 私鑰解密
string s = "123".Crc32();// 生成crc32摘要
string s = "123".Crc64();// 生成crc64摘要
string s = "123".SHA256();// 生成SHA256摘要
string pub="hello,world!";
string hidden="ldqk";
var str = pub.InjectZeroWidthString(hidden); // 擴(kuò)展函數(shù)調(diào)用:將"ldqk"以零寬字符串的方式隱藏在"hello,world!"中
var str = ZeroWidthCodec.Encrypt(pub,hidden); // 類調(diào)用:將"ldqk"以零寬字符串的方式隱藏在"hello,world!"中
var dec = str.DecodeZeroWidthString(); // 擴(kuò)展函數(shù)調(diào)用:將包含零寬字符串的密文解密出隱藏字符串"ldqk"
var dec = ZeroWidthCodec.Decrypt(str); // 類調(diào)用:將包含零寬字符串的密文解密出隱藏字符串"ldqk"
var enc = hidden.EncodeToZeroWidthText(); // 擴(kuò)展函數(shù)調(diào)用:將字符串編碼成零寬字符串
var enc = ZeroWidthCodec.Encode(); // 類調(diào)用:將字符串編碼成零寬字符串
17、實(shí)體校驗(yàn)
public class MyClass
{
[IsEmail] //可在appsetting.json中添加EmailDomainWhiteList配置郵箱域名白名單,逗號(hào)分隔
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]//密碼復(fù)雜度校驗(yàn)
public string Password { get; set; }
[EnumOf] // 檢測(cè)是否是有效枚舉值
public MyEnum MyEnum { get; set; }
[MinItemsCount(1)] // 檢測(cè)集合元素最少1個(gè)
public List<string> Strs { get; set; }
}
18、HTML操作
List<string> srcs = "html".MatchImgSrcs().ToList();// 獲取html字符串里所有的img標(biāo)簽的src屬性
var imgTags = "html".MatchImgTags();//獲取html字符串里的所有的img標(biāo)簽
var str="html".RemoveHtmlTag(); // 去除html標(biāo)簽
...
19、DateTime擴(kuò)展
double milliseconds = DateTime.Now.GetTotalMilliseconds();// 獲取毫秒級(jí)時(shí)間戳
double microseconds = DateTime.Now.GetTotalMicroseconds();// 獲取微秒級(jí)時(shí)間戳
double nanoseconds = DateTime.Now.GetTotalNanoseconds();// 獲取納秒級(jí)時(shí)間戳
double seconds = DateTime.Now.GetTotalSeconds();// 獲取秒級(jí)時(shí)間戳
double minutes = DateTime.Now.GetTotalMinutes();// 獲取分鐘級(jí)時(shí)間戳
...
20、IP地址和URL
bool inRange = "192.168.2.2".IpAddressInRange("192.168.1.1","192.168.3.255");// 判斷IP地址是否在這個(gè)地址段里
bool isPrivateIp = "172.16.23.25".IsPrivateIP();// 判斷是否是私有地址
bool isExternalAddress = "http://baidu.com".IsExternalAddress();// 判斷是否是外網(wǎng)的URL
//以下需要配置baiduAK
string isp = "114.114.114.114".GetISP(); // 獲取ISP運(yùn)營(yíng)商信息
PhysicsAddress physicsAddress = "114.114.114.114".GetPhysicsAddressInfo().Result;// 獲取詳細(xì)地理信息對(duì)象
Tuple<string, List<string>> ipAddressInfo = "114.114.114.114".GetIPAddressInfo().Result;// 獲取詳細(xì)地理信息集合
21、元素去重
var list = new List<MyClass>()
{
new MyClass()
{
Email = "[email protected]"
},
new MyClass()
{
Email = "[email protected]"
},
new MyClass()
{
Email = "[email protected]"
}
};
List<MyClass> classes = list.DistinctBy(c => c.Email).ToList();
Console.WriteLine(classes.Count==1);//True
22、枚舉擴(kuò)展
public enum MyEnum
{
[Display(Name = "讀")]
[Description("讀")]
Read,
[Display(Name = "寫")]
[Description("寫")]
Write
}
Dictionary<int, string> dic1 = typeof(MyEnum).GetDictionary();// 獲取枚舉值和字符串表示的字典映射
var dic2 = typeof(MyEnum).GetDescriptionAndValue();// 獲取字符串表示和枚舉值的字典映射
string desc = MyEnum.Read.GetDescription();// 獲取Description標(biāo)簽
string display = MyEnum.Read.GetDisplay();// 獲取Display標(biāo)簽的Name屬性
var value = typeof(MyEnum).GetValue("Read");//獲取字符串表示值對(duì)應(yīng)的枚舉值
string enumString = 0.ToEnumString(typeof(MyEnum));// 獲取枚舉值對(duì)應(yīng)的字符串表示
23、定長(zhǎng)隊(duì)列和ConcurrentHashSet實(shí)現(xiàn)
如果是.NET5及以上,推薦使用框架自帶的Channel實(shí)現(xiàn)該功能
LimitedQueue<string> queue = new LimitedQueue<string>(32);// 聲明一個(gè)容量為32個(gè)元素的定長(zhǎng)隊(duì)列
ConcurrentLimitedQueue<string> queue = new ConcurrentLimitedQueue<string>(32);// 聲明一個(gè)容量為32個(gè)元素的線程安全的定長(zhǎng)隊(duì)列
var set = new ConcurrentHashSet<string>(); // 用法和hashset保持一致
24、反射操作
MyClass myClass = new MyClass();
PropertyInfo[] properties = myClass.GetProperties();// 獲取屬性列表
myClass.SetProperty("Email","[email protected]");//給對(duì)象設(shè)置值
myClass.DeepClone(); // 對(duì)象深拷貝,帶嵌套層級(jí)的
25、獲取線程內(nèi)唯一對(duì)象
CallContext<T>.SetData("db",dbContext);//設(shè)置線程內(nèi)唯一對(duì)象
CallContext<T>.GetData("db");//獲取線程內(nèi)唯一對(duì)象
26、郵件發(fā)送
new Email()
{
SmtpServer = "smtp.masuit.com",// SMTP服務(wù)器
SmtpPort = 25, // SMTP服務(wù)器端口
EnableSsl = true,//使用SSL
Username = "[email protected]",// 郵箱用戶名
Password = "123456",// 郵箱密碼
Tos = "[email protected],[email protected]", //收件人
Subject = "測(cè)試郵件",//郵件標(biāo)題
Body = "你好啊",//郵件內(nèi)容
}.SendAsync(s =>
{
Console.WriteLine(s);// 發(fā)送成功后的回調(diào)
});// 異步發(fā)送郵件
27、圖像的簡(jiǎn)單處理
ImageUtilities.CompressImage(@"F:\src\1.jpg", @"F:\dest\2.jpg");//無損壓縮圖片
"base64".SaveDataUriAsImageFile();// 將Base64編碼轉(zhuǎn)換成圖片
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);//轉(zhuǎn)換成黑白
Bitmap newBmp = bmp.CutAndResize(new Rectangle(0, 0, 1600, 900), 160, 90);//裁剪并縮放
bmp.RevPicLR(bmp.Width, bmp.Height);//左右鏡像
bmp.RevPicUD(bmp.Width, bmp.Height);//上下鏡像
var marker=ImageWatermarker(stream);
stream=maker.AddWatermark("水印文字","字體文件",字體大小,color,水印位置,邊距); // 給圖片添加水印
stream=maker.AddWatermark(水印圖片,水印位置,邊距,字體大小,字體); // 給圖片添加水印
// 圖像相似度對(duì)比
var hasher = new ImageHasher();
var hash1 = hasher.DifferenceHash256("圖片1"); // 使用差分哈希算法計(jì)算圖像的256位哈希
var hash2 = hasher.DifferenceHash256("圖片2"); // 使用差分哈希算法計(jì)算圖像的256位哈希
//var hash1 = hasher.AverageHash64("圖片1"); // 使用平均值算法計(jì)算圖像的64位哈希
//var hash2 = hasher.AverageHash64("圖片2"); // 使用平均值算法計(jì)算圖像的64位哈希
//var hash1 = hasher.DctHash("圖片1"); // 使用DCT算法計(jì)算圖像的64位哈希
//var hash2 = hasher.DctHash("圖片2"); // 使用DCT算法計(jì)算圖像的64位哈希
//var hash1 = hasher.MedianHash64("圖片1"); // 使用中值算法計(jì)算給定圖像的64位哈希
//var hash2 = hasher.MedianHash64("圖片2"); // 使用中值算法計(jì)算給定圖像的64位哈希
var sim=ImageHasher.Compare(hash1,hash2); // 圖片的相似度,范圍:[0,1]
var imageFormat=stream.GetImageType(); // 獲取圖片的真實(shí)格式
28、隨機(jī)數(shù)
Random rnd = new Random();
int num = rnd.StrictNext();//產(chǎn)生真隨機(jī)數(shù)
double gauss = rnd.NextGauss(20,5);//產(chǎn)生正態(tài)高斯分布的隨機(jī)數(shù)
var s = new NumberFormater(62).ToString(new Random().Next(100000, int.MaxValue));//生成隨機(jī)字符串
29、權(quán)重篩選功能
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();//按權(quán)重選出1個(gè)元素
var list=data.WeightedItems(2);//按權(quán)重選出2個(gè)元素
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();//按權(quán)重選出1個(gè)元素
var list = selector.SelectMultiple(3);//按權(quán)重選出3個(gè)元素
30、EF Core支持AddOrUpdate方法
/// <summary>
/// 按Id添加或更新文章實(shí)體
/// </summary>
public override Post SavePost(Post t)
{
DataContext.Set<Post>().AddOrUpdate(t => t.Id, t);
return t;
}
31、敏感信息掩碼
"13123456789".Mask(); // 131****5678
"[email protected]".MaskEmail(); // a****[email protected]
32、集合擴(kuò)展
var list = new List<string>()
{
"1","3","3","3"
};
list.AddRangeIf(s => s.Length > 1, "1", "11"); // 將被添加元素中的長(zhǎng)度大于1的元素添加到list
list.AddRangeIfNotContains("1", "11"); // 將被添加元素中不包含的元素添加到list
list.RemoveWhere(s => s.Length<1); // 將集合中長(zhǎng)度小于1的元素移除
list.InsertAfter(0, "2"); // 在第一個(gè)元素之后插入
list.InsertAfter(s => s == "1", "2"); // 在元素"1"后插入
var dic = list.ToDictionarySafety(s => s); // 安全的轉(zhuǎn)換成字典類型,當(dāng)鍵重復(fù)時(shí)只添加一個(gè)鍵
var dic = list.ToConcurrentDictionary(s => s); // 轉(zhuǎn)換成并發(fā)字典類型,當(dāng)鍵重復(fù)時(shí)只添加一個(gè)鍵
var dic = list.ToDictionarySafety(s => s, s => s.GetHashCode()); // 安全的轉(zhuǎn)換成字典類型,當(dāng)鍵重復(fù)時(shí)只添加一個(gè)鍵
dic.AddOrUpdate("4", 4); // 添加或更新鍵值對(duì)
dic.AddOrUpdate(new Dictionary<string, int>()
{
["5"] = 5,["55"]=555
}); // 批量添加或更新鍵值對(duì)
dic.AddOrUpdate("5", 6, (s, i) => 66); // 如果是添加,則值為6,若更新則值為66
dic.AddOrUpdate("5", 6, 666); // 如果是添加,則值為6,若更新則值為666
dic.GetOrAdd("7",77); // 字典獲取或添加元素
dic.GetOrAdd("7",()=>77); // 字典獲取或添加元素
dic.AsConcurrentDictionary(); // 普通字典轉(zhuǎn)換成并發(fā)字典集合
var table=list.ToDataTable(); // 轉(zhuǎn)換成DataTable類型
table.AddIdentityColumn(); //給DataTable增加一個(gè)自增列
table.HasRows(); // 檢查DataTable 是否有數(shù)據(jù)行
table.ToList<T>(); // datatable轉(zhuǎn)List
var set = list.ToHashSet(s=>s.Name);// 轉(zhuǎn)HashSet
var cts = new CancellationTokenSource(100); //取消口令
await list.ForeachAsync(async i=>{
await Task.Delay(100);
Console.WriteLine(i);
},cts.Token); // 異步foreach
await list.ForAsync(async (item,index)=>{
await Task.Delay(100);
Console.WriteLine(item+"_"+index);
},cts.Token); // 異步for,帶索引編號(hào)
await list.SelectAsync(async i=>{
await Task.Delay(100);
return i*10;
}); // 異步Select
await list.SelectAsync(async (item,index)=>{
await Task.Delay(100);
return item*10;
}); // 異步Select,帶索引編號(hào)
string s=list.Join(",");//將字符串集合連接成逗號(hào)分隔的單字符串
var max=list.MaxOrDefault(); // 取最大值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var max=list.MaxOrDefault(selector); // 取最大值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var max=list.MaxOrDefault(selector,default); // 取最大值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var max=list.MinOrDefault(); // 取最小值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var max=list.MinOrDefault(selector); // 取最小值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var max=list.MinOrDefault(selector,default); // 取最小值,當(dāng)集合為空的時(shí)候不會(huì)報(bào)錯(cuò)
var stdDev=list.Select(s=>s.ConvertTo<int>()).StandardDeviation(); // 求標(biāo)準(zhǔn)差
var pages=queryable.ToPagedList(1,10); // 分頁查詢
var pages=await queryable.ToPagedListAsync(1,10); // 分頁查詢
var nums=Enumerable.Range(1, 10).ExceptBy(Enumerable.Range(5, 10), i => i); // 按字段取差集
var nums=Enumerable.Range(1, 10).IntersectBy(Enumerable.Range(5, 10), i => i); // 按字段取交集
var nums=Enumerable.Range(1, 10).SequenceEqual(Enumerable.Range(5, 10), i => i); // 判斷序列相等
var nums=Enumerable.Range(1, 10).OrderByRandom(); // 隨機(jī)排序
// 多個(gè)集合取交集
var list=new List<List<MyClass>>(){
new List<MyClass>(){
new MyClass(){Name="aa",Age=11},
new MyClass(){Name="bb",Age=12},
new MyClass(){Name="cc",Age=13},
},
new List<MyClass>(){
new MyClass(){Name="bb",Age=12},
new MyClass(){Name="cc",Age=13},
new MyClass(){Name="dd",Age=14},
},
new List<MyClass>(){
new MyClass(){Name="cc",Age=13},
new MyClass(){Name="dd",Age=14},
new MyClass(){Name="ee",Age=15},
},
};
var sect=list.IntersectAll(m=>m.Name); // new MyClass(){Name="cc",Age=13}
var list=new List<List<int>>(){
new(){1,2,3},
new(){2,3,4},
new(){3,4,5}
};
var sect=list.IntersectAll();// [3]
// 集合元素改變其索引位置
list.ChangeIndex(item,3); // 將元素item的索引位置變?yōu)榈?個(gè)
list.ChangeIndex(t=>t.Id=="123",2); // 將id為123的元素的索引位置變?yōu)榈?個(gè)
33、Mime類型
var mimeMapper = new MimeMapper();
var ext = mimeMapper.GetExtensionFromMime("image/jpeg"); // .jpg
var mime = mimeMapper.GetMimeFromExtension(".jpg"); // image/jpeg
34、日期時(shí)間擴(kuò)展
DateTime.Now.GetTotalSeconds(); // 獲取該時(shí)間相對(duì)于1970-01-01 00:00:00的秒數(shù)
DateTime.Now.GetTotalMilliseconds(); // 獲取該時(shí)間相對(duì)于1970-01-01 00:00:00的毫秒數(shù)
DateTime.Now.GetTotalMicroseconds(); // 獲取該時(shí)間相對(duì)于1970-01-01 00:00:00的微秒數(shù)
DateTime.Now.GetTotalNanoseconds(); // 獲取該時(shí)間相對(duì)于1970-01-01 00:00:00的納秒數(shù)
var indate=DateTime.Parse("2020-8-3").In(DateTime.Parse("2020-8-2"),DateTime.Parse("2020-8-4"));//true
DateTime time="2021-1-1 8:00:00".ToDateTime(); //字符串轉(zhuǎn)DateTime
//時(shí)間段計(jì)算工具
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")); //連接兩個(gè)時(shí)間段,結(jié)果:2020-8-3~2020-8-6
range.In(DateTime.Parse("2020-8-3"), DateTime.Parse("2020-8-6"));//判斷是否在某個(gè)時(shí)間段內(nèi),true
var (intersected,range2) = range.Intersect(DateTime.Parse("2020-8-4"), DateTime.Parse("2020-8-6"));//兩個(gè)時(shí)間段是否相交,(true,2020-8-3~2020-8-4)
range.Contains(DateTime.Parse("2020-8-3"), DateTime.Parse("2020-8-4"));//判斷是否包含某個(gè)時(shí)間段,true
...
35、流相關(guān)
stream.SaveAsMemoryStream(); // 任意流轉(zhuǎn)換成內(nèi)存流
stream.ToArray(); // 任意流轉(zhuǎn)換成二進(jìn)制數(shù)組
stream.ToArrayAsync(); // 任意流轉(zhuǎn)換成二進(jìn)制數(shù)組
stream.ShuffleCode(); // 流洗碼,在流的末端隨即增加幾個(gè)空字節(jié),重要數(shù)據(jù)請(qǐng)謹(jǐn)慎使用,可能造成流損壞
// 池化內(nèi)存流,用法與MemorySteam保持一致
using var ms=PooledMemoryStream();
// 大型內(nèi)存流,最大可支持1TB內(nèi)存數(shù)據(jù),推薦當(dāng)數(shù)據(jù)流大于2GB時(shí)使用,用法與MemorySteam保持一致
using var ms=LargeMemoryStream();
//文件流快速復(fù)制
FileStream fs = new FileStream(@"D:\boot.vmdk", FileMode.OpenOrCreate, FileAccess.ReadWrite);
{
//fs.CopyToFile(@"D:\1.bak");//同步復(fù)制大文件
fs.CopyToFileAsync(@"D:\1.bak");//異步復(fù)制大文件
string md5 = fs.GetFileMD5Async().Result;//異步獲取文件的MD5
string sha1 = fs.GetFileSha1();//異步獲取文件的SHA1
}
memoryStream.SaveFile("filename"); // 將內(nèi)存流轉(zhuǎn)儲(chǔ)成文件
36、數(shù)值轉(zhuǎn)換
1.2345678901.Digits8(); // 將小數(shù)截?cái)酁?位
1.23.ConvertTo<int>(); // 小數(shù)轉(zhuǎn)int
1.23.ConvertTo<T>(); // 小數(shù)轉(zhuǎn)T基本類型
bool b=1.23.TryConvertTo<T>(out result); // 小數(shù)轉(zhuǎn)T基本類型
var num=1.2345.ToDecimal(2); //轉(zhuǎn)decimal并保留兩位小數(shù)
37、INI配置文件操作(僅支持Windows)
INIFile ini=new INIFile("filename.ini");
ini.IniWriteValue(section,key,value); // 寫值
ini.IniReadValue(section,key); // 讀值
ini.ClearAllSection(); // 清空所有配置節(jié)
ini.ClearSection(section); // 清空配置節(jié)
38、雷達(dá)圖計(jì)算引擎
應(yīng)用場(chǎng)景:計(jì)算兩個(gè)多邊形的相似度,用戶畫像之類的
var points=RadarChartEngine.ComputeIntersection(chart1,chart2); //獲取兩個(gè)多邊形的相交區(qū)域
points.ComputeArea(); //計(jì)算多邊形面積
39、樹形結(jié)構(gòu)實(shí)現(xiàn)
基本接口類: ITreeChildren:帶Children屬性的接口 ITreeParent:帶Parent屬性的接口 ITree:繼承ITreeParent和ITreeChildren,同時(shí)多了Name屬性
相關(guān)擴(kuò)展方法:
trees.Filter(func); // 從樹形集合中過濾
trees.Flatten(); // 將數(shù)據(jù)平鋪開
tree.AllChildren(); // 獲取所有的子級(jí)
tree.AllParent(); // 獲取所有的父級(jí)
tree.IsRoot(); // 是否是根節(jié)點(diǎn)
tree.IsLeaf(); // 是否是葉子節(jié)點(diǎn)
tree.Level(); // 所處深度/層級(jí)
tree.Path(); // 全路徑
var tree=list.ToTree(c => c.Id, c => c.Pid);//繼承自ITreeParent<T>, ITreeChildren<T>的集合轉(zhuǎn)換成樹形結(jié)構(gòu)
var tree=list.ToTreeGeneral(c => c.Id, c => c.Pid);//一般的集合轉(zhuǎn)換成樹形結(jié)構(gòu)
40、簡(jiǎn)單的Excel導(dǎo)出
需要額外依賴包:Masuit.Tools.Excel
var stream=list.Select(item=>new{
姓名=item.Name,
年齡=item.Age,
item.Gender,
Avatar=Image.FromStream(filestream) //圖片列
}).ToDataTable().ToExcel("Sheet1"); //自定義列名導(dǎo)出
var stream=list.ToDataTable("Sheet1").ToExcel("文件密碼");
一些約定規(guī)則:
1、圖片列支持Stream、Bitmap、IEnumerable、IEnumerable、IDictionary<string,Stream>、IDictionary<string,MemoryStream>、IDictionary<string,Bitmap>類型;
2、其中,如果是IDictionary類型的圖片列,字典的鍵為圖片超鏈接的完整url;
3、默認(rèn)字段名作為列名導(dǎo)出;
4、若list是一個(gè)具體的強(qiáng)類型,默認(rèn)會(huì)先查找每個(gè)字段的Description標(biāo)記,若有Description標(biāo)記,則取Description標(biāo)記作為列名顯示
5、ToExcel方法支持DataTable、List、Dictionary<string, DataTable>類型的直接調(diào)用
41、EFCore實(shí)體對(duì)比功能
獲取指定實(shí)體的變更
var changes=dbContext.GetChanges<Post>();//獲取變更字段信息
var added=dbContext.GetAdded<Post>();//獲取添加的實(shí)體字段信息
var removed=dbContext.GetRemoved<Post>();//獲取被移除的實(shí)體字段信息
var allchanges=dbContext.GetAllChanges<Post>();//獲取增刪改的實(shí)體字段信息
獲取所有實(shí)體的變更
var changes=dbContext.GetChanges();//獲取變更字段信息
var added=dbContext.GetAdded();//獲取添加的實(shí)體字段信息
var removed=dbContext.GetRemoved();//獲取被移除的實(shí)體字段信息
var allchanges=dbContext.GetAllChanges();//獲取增刪改的實(shí)體字段信息
對(duì)比信息包含屬性信息、舊值、新值、實(shí)體信息、鍵信息、變更狀態(tài)等
42、任何類型支持鏈?zhǔn)秸{(diào)用
a.Next(func1).Next(func2).Next(func3);
"123".Next(s=>s.ToInt32()).Next(x=>x*2).Next(x=>Math.Log(x));
43、Newtonsoft.Json的只允許字段反序列化行為的契約解釋器
DeserializeOnlyContractResolver
該解釋器針對(duì)類屬性被DeserializeOnlyJsonPropertyAttribute標(biāo)記的,在反序列化的時(shí)候生效,在序列化的時(shí)候忽略
public class ClassDto
{
[DeserializeOnlyJsonProperty]
public string MyProperty { get; set; }
public int Num { get; set; }
}
JsonConvert.SerializeObject(new MyClass(),new JsonSerializerSettings()
{
ContractResolver = new DeserializeOnlyContractResolver() // 配置使用DeserializeOnlyContractResolver解釋器
});
如果是WebAPI全局使用:
//在Startup.ConfigureServices中
services.AddMvc().AddNewtonsoftJson(options =>
{
var resolver = new DeserializeOnlyContractResolver();
resolver.NamingStrategy = new CamelCaseNamingStrategy();
options.SerializerSettings.ContractResolver = resolver;
});
FallbackJsonPropertyResolver
該解釋器針對(duì)某個(gè)屬性設(shè)置多個(gè)別名,反序列化時(shí)支持多個(gè)別名key進(jìn)行綁定,彌補(bǔ)官方JsonProperty別名屬性只能設(shè)置單一別名的不足
public class ClassDto
{
[FallbackJsonProperty("MyProperty","a","b")]
public string MyProperty { get; set; }
public int Num { get; set; }
}
JsonConvert.SerializeObject(new MyClass(),new JsonSerializerSettings()
{
ContractResolver = new FallbackJsonPropertyResolver() // 配置使用FallbackJsonPropertyResolver解釋器
});
CompositeContractResolver
該解釋器是DeserializeOnlyContractResolver和FallbackJsonPropertyResolver的融合版
44、ASP.NET Core Action同時(shí)支持queryString、表單和json請(qǐng)求類型的模型綁點(diǎn)器BodyOrDefaultModelBinder
用法:
引入包:Masuit.Tools.AspNetCore
PM> Install-Package Masuit.Tools.AspNetCore
Startup配置:
services.AddMvc(options =>
{
options.ModelBinderProviders.InsertBodyOrDefaultBinding();
})
在action的參數(shù)模型前打上標(biāo)記:[FromBodyOrDefault]即可,當(dāng)然也可以省略,示例代碼如下:
[HttpGet("query"),HttpPost("query")]
public IActionResult Query([FromBodyOrDefault]QueryModel query)
{
return Ok(...);
}
[HttpGet("query"),HttpPost("query")]
public IActionResult Query([FromBodyOrDefault]int id,[FromBodyOrDefault]string name)
{
return Ok(...);
}
45、字符串SimHash相似度算法
var dis="12345678".HammingDistance("1234567");
var dis=new SimHash("12345678").HammingDistance(new SimHash("1234567"));
46、真實(shí)文件類型探測(cè)
// 多種方式,任君調(diào)用
var detector=new FileInfo(filepath).DetectFiletype();
//var detector=File.OpenRead(filepath).DetectFiletype();
//var detector=FileSignatureDetector.DetectFiletype(filepath);
detector.Precondition;//基礎(chǔ)文件類型
detector.Extension;//真實(shí)擴(kuò)展名
detector.MimeType;//MimeType
detector.FormatCategories;//格式類別
默認(rèn)支持的文件類型
| 擴(kuò)展名 | 說明 |
|---|---|
| 3GP | 3GPP, 3GPP 2 |
| 7Z | 7-Zip |
| APK | ZIP based Android Package |
| AVI | Audio-Video Interleave |
| SH | Shell Script |
| BPLIST | Binary Property List |
| BMP, DIB | Bitmap |
| BZ2 | Bunzip2 Compressed |
| CAB | Microsoft Cabinet |
| CLASS | Java Bytecode |
| CONFIG | .NET Configuration File |
| CRT, CERT | Certificate |
| CUR | Cursor |
| DB | Windows Thumbs.db Thumbnail Database |
| DDS | DirectDraw Surface |
| DLL | Windows Dynamic Linkage Library |
| DMG | Apple Disk Mount Image |
| DMP | Windows Memory Dump File |
| DOC | Microsoft Office Word 97-2003 Document |
| DOCX | Microsoft Office Word OpenXML Document |
| EPUB | e-Pub Document |
| EXE | Windows Executive |
| FLAC | Loseless Audio |
| FLV | Flash Video |
| GIF | Graphics Interchage Format |
| GZ | GZ Compressed |
| HDP | HD Photo(JPEG XR) Image |
| HWP | Legacy HWP, HWPML, CFBF HWP |
| ICO | Icon |
| INI | Initialization File |
| ISO | ISO-9660 Disc Image |
| LNK | Windows Shortcut Link |
| JP2 | JPEG 2000 Image |
| JPG, JPEG | Joint Photographic Experts Group Image |
| LZH | LZH Compressed |
| M4A | MP4 Container Contained Audio Only |
| M4V | MP4 Container Contained Video |
| MID | Midi Sound |
| MKA | Matroska Container Contained Audio Only |
| MKV | Matroska Container Contained Video |
| MOV | QuickTime Movie Video |
| MP4 | MP4 Container Contained Contents |
| MSI | Microsoft Installer |
| OGG | OGG Video or Audio |
| ODF | OpenDocument Formula |
| ODG | OpenDocument Graphics |
| ODP | OpenDocument Presentation |
| ODS | OpenDocument Spreadsheet |
| ODT | OpenDocument Text |
| PAK | PAK Archive or Quake Archive |
| PDB | Microsoft Program Database |
| Portable Document Format | |
| PFX | Microsoft Personal Information Exchange Certificate |
| PNG | Portable Network Graphics Image |
| PPT | Microsoft Office PowerPoint 97-2003 Document |
| PPTX | Microsoft Office PowerPoint OpenXML Document |
| PPSX | Microsoft Office PowerPoint OpenXML Document for Slideshow only |
| PSD | Photoshop Document |
| RAR | WinRAR Compressed |
| REG | Windows Registry |
| RPM | RedHat Package Manager Package |
| RTF | Rich Text Format Document |
| SLN | Microsoft Visual Studio Solution |
| SRT | SubRip Subtitle |
| SWF | Shockwave Flash |
| SQLITE, DB | SQLite Database |
| TAR | pre-ISO Type and UStar Type TAR Package |
| TIFF | Tagged Image File Format Image |
| TXT | Plain Text |
| WAV | Wave Audio |
| WASM | Binary WebAssembly |
| WEBM | WebM Video |
| WEBP | WebP Image |
| XAR | XAR Package |
| XLS | Microsoft Office Excel 97-2003 Document |
| XLSX | Microsoft Office Excep OpenXML Document |
| XML | Extensible Markup Language Document |
| Z | Z Compressed |
| ZIP | ZIP Package |
Asp.Net MVC和Asp.NetCore的支持?jǐn)帱c(diǎn)續(xù)傳和多線程下載的ResumeFileResult
在ASP.NET Core中通過MVC/WebAPI應(yīng)用程序傳輸文件數(shù)據(jù)時(shí)使用斷點(diǎn)續(xù)傳以及多線程下載支持。
它提供了ETag標(biāo)頭以及Last-Modified標(biāo)頭。 它還支持以下前置條件標(biāo)頭:If-Match,If-None-Match,If-Modified-Since,If-Unmodified-Since,If-Range。
支持 ASP.NET Core 2.0+
從.NET Core2.0開始,ASP.NET Core內(nèi)部支持?jǐn)帱c(diǎn)續(xù)傳。 因此只是對(duì)FileResult做了一些擴(kuò)展。
只留下了“Content-Disposition” Inline的一部分。 所有代碼都依賴于基礎(chǔ).NET類。
如何使用
.NET Framework
在你的控制器中,你可以像在FileResult一樣的方式使用它。
using Masuit.Tools.Mvc;
using Masuit.Tools.Mvc.ResumeFileResult;
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方法調(diào)用中配置服務(wù):
using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
public void ConfigureServices(IServiceCollection services)
{
services.AddResumeFileResult();
}
然后在你的控制器中,你可以像在FileResult一樣的方式使用它。
using Masuit.Tools.AspNetCore.ResumeFileResults.Extensions;
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;
}
以上示例將為您的數(shù)據(jù)提供“Content-Disposition:attachment”。 當(dāng)沒有提供fileName時(shí),數(shù)據(jù)將作為“Content-Disposition:inline”提供。 另外,它可以提供ETag和LastModified標(biāo)頭。
[HttpGet("virtual/{fileName}")]
public IActionResult VirtualFile(bool fileName)
{
var result = new ResumeVirtualFileResult("TestFile.txt", "text/plain")
{
FileInlineName = "TestFile.txt",
LastModified = _lastModified
};
return result;
}
推薦項(xiàng)目
基于EntityFrameworkCore和Lucene.NET實(shí)現(xiàn)的全文檢索搜索引擎
1、Masuit.LuceneEFCore.SearchEngine
https://github.com/ldqk/Masuit.LuceneEFCore.SearchEngine
2、開源博客系統(tǒng)Masuit.MyBlogs
https://github.com/ldqk/Masuit.MyBlogs
轉(zhuǎn)自:ldqk
鏈接:github.com/ldqk/Masuit.Tools
