├── Source ├── xmtool.png ├── Captcha │ ├── CaptchaData.cs │ ├── CaptchaOption.cs │ ├── Slider_Templates │ │ ├── 1 │ │ │ ├── hole.png │ │ │ └── slider.png │ │ ├── 2 │ │ │ ├── hole.png │ │ │ └── slider.png │ │ ├── 3 │ │ │ ├── hole.png │ │ │ └── slider.png │ │ ├── 4 │ │ │ ├── hole.png │ │ │ └── slider.png │ │ └── 5 │ │ │ ├── hole.png │ │ │ └── slider.png │ ├── Implements │ │ ├── CharacterCaptchaData.cs │ │ ├── SlidingCaptchaOption.cs │ │ ├── SlidingCaptchaData.cs │ │ ├── CharacterCaptchaOption.cs │ │ └── CharacterCaptcha.cs │ ├── ICaptcha.cs │ ├── CaptchaResult.cs │ └── CaptchaTool.cs ├── Json │ ├── JsonTool.cs │ └── JsonConfigParser.cs ├── Web │ ├── HttpSecurity.cs │ └── WebTool.cs ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Oss │ ├── IOssProvider.cs │ ├── OssTool.cs │ └── Providers │ │ ├── QiniuOss.cs │ │ ├── AlibabaOss.cs │ │ └── TencentOss.cs ├── Sms │ ├── SmsTool.cs │ ├── ISmsProvider.cs │ └── Providers │ │ ├── AlibabaSms.cs │ │ └── TencentSms.cs ├── TypeTool.cs ├── RandomTool.cs ├── DynamicObject │ └── DynamicObjectExtMetaObject.cs ├── Xmtool.cs ├── HashTool.cs ├── Source.csproj ├── CryptoTool.cs ├── ImageTool.cs ├── DateTimeTool.cs ├── MailTool.cs └── RegexTool.cs ├── Test ├── resources │ ├── appsettings.Development.json │ ├── slider_backgrounds │ │ ├── 01.jpg │ │ ├── 02.jpg │ │ ├── 03.jpg │ │ ├── 04.jpg │ │ └── 05.jpg │ ├── appsettings.json │ └── ioc.xml ├── SmsTest.cs ├── HashTest.cs ├── CryptoTest.cs ├── OssTest.cs ├── Test.csproj ├── ImageTest.cs ├── DateTimeTest.cs ├── WebTest.cs ├── JsonTest.cs ├── CaptchaTest.cs ├── XmlTest.cs └── TypeTest.cs ├── docs ├── favicon.ico ├── static │ ├── random.md │ ├── what.md │ ├── crypto.md │ ├── hash.md │ ├── json.md │ ├── types.md │ ├── config.json │ ├── sendmail.md │ ├── oss.md │ ├── sendsms.md │ ├── datetime.md │ ├── captcha.md │ ├── image.md │ ├── dynamicobj.md │ ├── xml.md │ └── regex.md ├── index.html └── css │ └── app.16207956.css ├── .gitignore ├── LICENSE ├── Xmtool.sln └── README.md /Source/xmtool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/xmtool.png -------------------------------------------------------------------------------- /Test/resources/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "This is a example." 3 | } -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /Source/Captcha/CaptchaData.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class CaptchaData 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Test/resources/slider_backgrounds/01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Test/resources/slider_backgrounds/01.jpg -------------------------------------------------------------------------------- /Test/resources/slider_backgrounds/02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Test/resources/slider_backgrounds/02.jpg -------------------------------------------------------------------------------- /Test/resources/slider_backgrounds/03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Test/resources/slider_backgrounds/03.jpg -------------------------------------------------------------------------------- /Test/resources/slider_backgrounds/04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Test/resources/slider_backgrounds/04.jpg -------------------------------------------------------------------------------- /Test/resources/slider_backgrounds/05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Test/resources/slider_backgrounds/05.jpg -------------------------------------------------------------------------------- /Source/Captcha/CaptchaOption.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class CaptchaOption 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/1/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/1/hole.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/2/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/2/hole.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/3/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/3/hole.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/4/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/4/hole.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/5/hole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/5/hole.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/1/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/1/slider.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/2/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/2/slider.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/3/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/3/slider.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/4/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/4/slider.png -------------------------------------------------------------------------------- /Source/Captcha/Slider_Templates/5/slider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/softwaiter/Xmtool/HEAD/Source/Captcha/Slider_Templates/5/slider.png -------------------------------------------------------------------------------- /Test/resources/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "Json Config Parser", 3 | 4 | "User": { 5 | "Name": "Wangxm", 6 | "Age": 18 7 | }, 8 | 9 | "Enable": true, 10 | 11 | "Country": ["China", "USA", "Russia"] //这是一个注释 12 | } 13 | -------------------------------------------------------------------------------- /Source/Captcha/Implements/CharacterCaptchaData.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class CharacterCaptchaData : CaptchaData 4 | { 5 | public CharacterCaptchaData() 6 | { 7 | } 8 | 9 | public CharacterCaptchaData(string code) 10 | { 11 | Code = code; 12 | } 13 | 14 | public string Code { get; set; } = null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Source/Captcha/ICaptcha.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public enum CaptchaKind 4 | { 5 | Character, 6 | Sliding 7 | } 8 | 9 | public interface ICaptcha 10 | { 11 | public CaptchaKind Type { get; } 12 | 13 | public ICaptcha Config(CaptchaOption option); 14 | 15 | public CaptchaResult Generate(CaptchaData data = null); 16 | 17 | public bool Validate(object source, object input); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Source/Json/JsonTool.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools.Json 2 | { 3 | public class JsonTool 4 | { 5 | private static JsonTool sJTool = new JsonTool(); 6 | 7 | private JsonTool() 8 | { 9 | } 10 | 11 | internal static JsonTool New() 12 | { 13 | return sJTool; 14 | } 15 | 16 | public JsonConfigParser ConfigParser() 17 | { 18 | return JsonConfigParser.New(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Source/Captcha/CaptchaResult.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class CaptchaResult 4 | { 5 | public CaptchaResult() 6 | { 7 | } 8 | 9 | public CaptchaResult(string validationData, string displayData) 10 | { 11 | ValidationData = validationData; 12 | DisplayData = displayData; 13 | } 14 | 15 | public string ValidationData { get; set; } 16 | public string DisplayData { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Source/Web/HttpSecurity.cs: -------------------------------------------------------------------------------- 1 | using Ganss.Xss; 2 | 3 | namespace CodeM.Common.Tools.Web 4 | { 5 | public class HttpSecurity 6 | { 7 | private static HttpSecurity sHS = new HttpSecurity(); 8 | public static HttpSecurity New() 9 | { 10 | return sHS; 11 | } 12 | 13 | private HtmlSanitizer mSanitizer = new HtmlSanitizer(); 14 | 15 | public string Xss(string str) 16 | { 17 | return mSanitizer.Sanitize(str); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/static/random.md: -------------------------------------------------------------------------------- 1 | # 随机值 2 | 3 | 基于整个工具包的精简设计原则,对于.NetCore框架已经提供且使用方便的功能,本工具包不会进行二次封装;因此,在随机值工具类中,没有提供获取随机数值的方法,目前只提供了一个生成随机验证码的方法,后续根据需要会持续增加。 4 | 5 | [生成验证码](#gen-captcha) 6 | 7 | #### 1. 生成验证码 8 | 9 | ###### public string RandomCaptcha(int len, bool onlyNumber = false) 10 | 11 | 说明:生成指定规格的验证码并返回。 12 | 13 | ```c# 14 | // 生成4位纯数字验证码 15 | string numCaptcha = Xmtool.Random().RandomCaptcha(4, true); 16 | // 生成6位字母和数字混合的验证码 17 | string captcha = Xmtool.Random().RandomCaptcha(6); 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the -------------------------------------------------------------------------------- /Source/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\net8.0\publish\ 10 | FileSystem 11 | net8.0 12 | false 13 | 14 | -------------------------------------------------------------------------------- /Source/Oss/IOssProvider.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace CodeM.Common.Tools 4 | { 5 | public enum OssProvider 6 | { 7 | Unset, 8 | Qiniu, 9 | Alibaba, 10 | Tencent 11 | } 12 | 13 | public interface IOssProvider 14 | { 15 | public IOssProvider Config(params string[] args); 16 | 17 | public IOssProvider SetUseHttps(bool useHttps); 18 | 19 | public IOssProvider SetContentType(string contentType); 20 | 21 | public string UploadFile(string bucketName, string filename, string key = null); 22 | 23 | public string UploadStream(string bucketName, Stream stream, string key = null); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/Sms/SmsTool.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools.Sms.Providers; 2 | 3 | namespace CodeM.Common.Tools.Sms 4 | { 5 | public class SmsTool 6 | { 7 | internal static ISmsProvider GetProvider(SmsProvider _typ) 8 | { 9 | switch (_typ) 10 | { 11 | case SmsProvider.Alibaba: 12 | return new AlibabaSms(); 13 | case SmsProvider.Tencent: 14 | return new TencentSms(); 15 | } 16 | return null; 17 | } 18 | 19 | internal static ISmsProvider New(SmsProvider _typ) 20 | { 21 | return GetProvider(_typ); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/Captcha/Implements/SlidingCaptchaOption.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class SlidingCaptchaOption : CaptchaOption 4 | { 5 | public SlidingCaptchaOption() 6 | { 7 | } 8 | 9 | public SlidingCaptchaOption(string backgroundDir) 10 | { 11 | BackgroundDir = backgroundDir; 12 | } 13 | 14 | public SlidingCaptchaOption(string backgroundDir, float resultError) 15 | : this(backgroundDir) 16 | { 17 | ResultError = resultError; 18 | } 19 | 20 | public string BackgroundDir { get; set; } 21 | 22 | public float ResultError { get; set; } = 0.02f; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/Captcha/CaptchaTool.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools.Captcha.Implements; 2 | 3 | namespace CodeM.Common.Tools.Captcha 4 | { 5 | public class CaptchaTool 6 | { 7 | internal static ICaptcha GetCaptcha(CaptchaKind kind) 8 | { 9 | switch (kind) 10 | { 11 | case CaptchaKind.Character: 12 | return new CharacterCaptcha(); 13 | case CaptchaKind.Sliding: 14 | return new SlidingCaptcha(); 15 | } 16 | return null; 17 | } 18 | 19 | internal static ICaptcha New(CaptchaKind kind) 20 | { 21 | return GetCaptcha(kind); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/Oss/OssTool.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools.Oss.Providers; 2 | 3 | namespace CodeM.Common.Tools.Oss 4 | { 5 | public class OssTool 6 | { 7 | internal static IOssProvider GetProvider(OssProvider _typ) 8 | { 9 | switch (_typ) 10 | { 11 | case OssProvider.Qiniu: 12 | return new QiniuOss(); 13 | case OssProvider.Alibaba: 14 | return new AlibabaOss(); 15 | case OssProvider.Tencent: 16 | return new TencentOss(); 17 | } 18 | return null; 19 | } 20 | 21 | internal static IOssProvider New(OssProvider _typ) 22 | { 23 | return GetProvider(_typ); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Source/Sms/ISmsProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CodeM.Common.Tools 4 | { 5 | public enum SmsProvider 6 | { 7 | Unset, 8 | Alibaba, 9 | Tencent 10 | } 11 | 12 | public interface ISmsProvider 13 | { 14 | public ISmsProvider Config(params string[] args); 15 | 16 | public bool Send(string templateParam, params string[] phoneNums); 17 | 18 | public bool Send2(string signName, string templateCode, string templateParam, params string[] phoneNums); 19 | 20 | public Task SendAsync(string templateParam, params string[] phoneNums); 21 | 22 | public Task Send2Async(string signName, string templateCode, string templateParam, params string[] phoneNums); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /docs/css/app.16207956.css: -------------------------------------------------------------------------------- 1 | #app{font-family:Helvetica Neue,Helvetica,tahoma,Hiragino Sans GB,PingFang SC,STHeitiSC-Light,Microsoft YaHei,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:#2c3e50;margin:0;padding:0;height:100vh;overflow-y:hidden}#components-layout-demo-top-side-2{height:100%}.ant-menu-inline .ant-menu-submenu-title{font-size:14px;font-weight:700}.ant-menu-submenu-inline>.ant-menu-submenu-title .ant-menu-submenu-arrow{margin-left:10px;right:inherit!important}.ant-menu-submenu-selected{color:rgba(0,0,0,.65)!important}.ant-menu .ant-menu-item-selected{background:transparent!important}.ant-menu-inline .ant-menu-item-selected:after{opacity:0!important}.markdown-body{height:100%;overflow-y:scroll;-webkit-box-sizing:border-box;box-sizing:border-box;min-width:200px;margin:0 auto;padding:0 45px}@media (max-width:767px){.markdown-body{padding:15px}} -------------------------------------------------------------------------------- /docs/static/what.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

5 | 一个简单易用的.NetCore工具类库(持续集成中...) 6 |

7 |
8 |
9 | 10 | ### 简介 11 | Xmtool是一个基于.NetCore框架的常用功能集成工具类库,目的是做成一个像Java语言中的Hutool类似的工具库,将和具体业务逻辑无关的常用功能和方法进行抽象、封装,集成到一个类库中,方便使用维护,提升开发效率。 12 | 13 | ### 原则 14 | Xmtool只对开发过程中经常使用到,且.NetCore框架没有提供或提供了但使用不友好的功能进行封装和集成;对于框架已经提供且使用方便的功能,不再进行二次封装。 15 | 16 | ### 反馈 17 | 18 | 提交问题反馈请说明正在使用的Xmtool版本。 19 | 20 | [Github issue](https://github.com/softwaiter/Xmtool/issues) 21 | 22 | ### 贡献 23 | 24 | 1. 在Gitee或者Github上fork项目到自己的repo 25 | 2. 把fork过去的项目也就是你的项目clone到你的本地 26 | 3. 修改代码 27 | 4. commit后push到自己的库 28 | 5. 登录Gitee或Github在你首页可以看到一个 pull request 按钮,点击它,填写一些说明信息,然后提交即可。 29 | 6. 等待维护者合并 -------------------------------------------------------------------------------- /Source/Captcha/Implements/SlidingCaptchaData.cs: -------------------------------------------------------------------------------- 1 | namespace CodeM.Common.Tools 2 | { 3 | public class SlidingCaptchaData : CaptchaData 4 | { 5 | public SlidingCaptchaData() 6 | { 7 | } 8 | 9 | public SlidingCaptchaData(int x, int y) 10 | { 11 | GapX = x; 12 | GapY = y; 13 | } 14 | 15 | public SlidingCaptchaData(int x, int y, int template) 16 | : this(x, y) 17 | { 18 | GapTemplate = template; 19 | } 20 | 21 | public SlidingCaptchaData(int template) 22 | { 23 | GapTemplate = template; 24 | } 25 | 26 | /// 27 | /// 缺口位置横坐标 28 | /// 29 | public int? GapX { get; set; } = null; 30 | 31 | /// 32 | /// 缺口位置纵坐标 33 | /// 34 | public int? GapY { get; set; } = null; 35 | 36 | /// 37 | /// 缺口模板索引号(目前提供0~4) 38 | /// 39 | public int? GapTemplate { get; set; } = null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Test/SmsTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Test 6 | { 7 | public class SmsTest 8 | { 9 | private ITestOutputHelper output; 10 | 11 | public SmsTest(ITestOutputHelper output) 12 | { 13 | this.output = output; 14 | } 15 | 16 | [Fact] 17 | public void Test() 18 | { 19 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Alibaba).Config("accessKeyId(替换成自己的)", "accessKeySecret(替换成自己的)", 20 | "阿里云短信签名(替换成自己的)", "模板编码(替换成自己的)"); 21 | bool ret = sms.Send("参数(替换成自己的,如:{\"code\":\"1234\"})", "136********"); 22 | Assert.True(ret); 23 | } 24 | 25 | [Fact] 26 | public void Test2() 27 | { 28 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Tencent).Config("secretId(替换成自己的)", "secretKey(替换成自己的)", 29 | "腾讯云短信签名(替换成自己的)", "模板Id(替换成自己的)", "appId(替换成自己的)"); 30 | bool ret = sms.Send("参数(替换成自己的,如:1234)", "136********"); 31 | Assert.True(ret); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Test/HashTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Test 6 | { 7 | public class HashTest 8 | { 9 | private ITestOutputHelper output; 10 | 11 | public HashTest(ITestOutputHelper output) { 12 | this.output = output; 13 | } 14 | 15 | [Fact] 16 | public void Md5() 17 | { 18 | string md5 = Xmtool.Hash().MD5("wangxiaoming"); 19 | output.WriteLine("wangxiaoming md5: " + md5); 20 | Assert.Equal(32, md5.Length); 21 | } 22 | 23 | [Fact] 24 | public void Sha1() { 25 | string sha1 = Xmtool.Hash().SHA1("wangxiaoming"); 26 | output.WriteLine("wangxiaoming sha1: " + sha1); 27 | Assert.Equal(40, sha1.Length); 28 | } 29 | 30 | [Fact] 31 | public void Sha256() { 32 | string sha256 = Xmtool.Hash().SHA256("wangxiaoming"); 33 | output.WriteLine("wangxiaoming sha256: " + sha256); 34 | Assert.Equal(64, sha256.Length); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 softwaiter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/Captcha/Implements/CharacterCaptchaOption.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | 3 | namespace CodeM.Common.Tools 4 | { 5 | public class CharacterCaptchaOption : CaptchaOption 6 | { 7 | public CharacterCaptchaOption() 8 | { 9 | } 10 | 11 | public CharacterCaptchaOption(int length, bool onlyNumber, 12 | int width, int height, Color backColor, Color borderColor) 13 | { 14 | Length = length; 15 | OnlyNumber = onlyNumber; 16 | Width = width; 17 | Height = height; 18 | BackColor = backColor; 19 | BorderColor = borderColor; 20 | } 21 | 22 | public int Length { get; set; } = 6; 23 | 24 | public bool OnlyNumber { get; set; } = true; 25 | 26 | public int Width { get; set; } = 300; 27 | 28 | public int Height { get; set; } = 120; 29 | 30 | public Color BackColor { get; set; } = Color.White; 31 | 32 | public Color BorderColor { get; set; } = Color.LightGray; 33 | 34 | public int ShapeNoise { get; set; } = 10; 35 | 36 | public int LineNoise { get; set; } = 3; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Test/CryptoTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Test 6 | { 7 | public class CryptoTest 8 | { 9 | private ITestOutputHelper output; 10 | 11 | public CryptoTest(ITestOutputHelper output) 12 | { 13 | this.output = output; 14 | } 15 | 16 | [Fact] 17 | public void Base64() 18 | { 19 | string source = "wangxiaoming"; 20 | string base64Encode = Xmtool.Crypto().Base64Encode(source); 21 | output.WriteLine("wangxiaoming base64: " + base64Encode); 22 | string base64Decode = Xmtool.Crypto().Base64Decode(base64Encode); 23 | Assert.Equal(base64Decode, source); 24 | } 25 | 26 | [Fact] 27 | public void Aes() 28 | { 29 | string source = "wangxiaoming"; 30 | string aesEncypted = Xmtool.Crypto().AESEncode(source, "test"); 31 | output.WriteLine("wangxiaoming aes: " + aesEncypted); 32 | string aesDecrypted = Xmtool.Crypto().AESDecode(aesEncypted, "test"); 33 | Assert.Equal(aesDecrypted, source); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/Web/WebTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Net.Http; 4 | 5 | namespace CodeM.Common.Tools.Web 6 | { 7 | public class WebTool 8 | { 9 | private static WebTool sWTool = new WebTool(); 10 | 11 | private WebTool() 12 | { 13 | } 14 | 15 | internal static WebTool New() 16 | { 17 | return sWTool; 18 | } 19 | 20 | private static ConcurrentDictionary sClients = new ConcurrentDictionary(); 21 | 22 | /// 23 | /// 本对象不支持并发,在多线程中请谨慎使用 24 | /// 25 | /// 26 | /// 27 | public HttpClientExt Client(string name = null) 28 | { 29 | if (string.IsNullOrWhiteSpace(name)) 30 | { 31 | name = DateTime.Now.Ticks.ToString(); 32 | } 33 | HttpClient client = sClients.GetOrAdd(name, new HttpClient()); 34 | return new HttpClientExt(client); 35 | } 36 | 37 | public HttpSecurity Security() 38 | { 39 | return HttpSecurity.New(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/static/crypto.md: -------------------------------------------------------------------------------- 1 | # 加密解密 2 | 3 | 加密解密是开发过程中多多少少必然会遇到的需求,Xmtool封装了最常用的Base64和AES对称加密方法;严格来讲,Base64不算加密解密,为了管理和使用方便,故放在加密解密模块。 4 | 5 | [Base64编码](#crypto-base64-1) 6 | 7 | [Base64解码](#crypto-base64-2) 8 | 9 | [AES加密](#crypto-aes-1) 10 | 11 | [AES解密](#crypto-aes-2) 12 | 13 | #### 1. Base64编码 14 | 15 | ###### public string Base64Encode(string text, string encoding = "utf-8") 16 | 17 | 说明:对传入字符串进行Base64编码并返回,默认字符串编码格式为UTF8。 18 | 19 | ```c# 20 | string base64Str = Xmtool.Crypto().Base64Encode("https://github.com/softwaiter"); 21 | // TODO 22 | ``` 23 | 24 | #### 2. Base64解码 25 | 26 | ###### public string Base64Decode(string base64Text, string encoding = "utf-8") 27 | 28 | 说明:对经过Base64编码的字符串进行解码,返回解码后的明文内容,默认解码编码格式为UTF8。 29 | 30 | ```c# 31 | string url = Xmtool.Crypto().Base64Decode("aHR0cHM6Ly9naXRodWIuY29tL3NvZnR3YWl0ZXI="); 32 | // TODO 33 | ``` 34 | 35 | #### 3. AES加密 36 | 37 | ###### public string AESEncode(string text, string key, string encoding = "utf-8") 38 | 39 | 说明:AES对称加密方法,key为加密的盐值,encoding为加密字符串的编码格式,默认为UTF8。 40 | 41 | ```c# 42 | string password = "admin@123"; 43 | string encryptedPass = Xmtool.Crypto().AESEncode(password, "salt123"); 44 | // TODO 45 | ``` 46 | 47 | #### 4. AES解密 48 | 49 | ###### public string AESDecode(string aesText, string key, string encoding = "utf-8") 50 | 51 | 说明:AES解密方法,解密时需使用和加密时相同的key和encoding编码格式。 52 | 53 | ```c# 54 | string password = Xmtool.Crypto().AESDecode("vi3G7kR7r5GaLglLOGGtzw==", "salt123"); 55 | // TODO 56 | ``` 57 | 58 | -------------------------------------------------------------------------------- /Xmtool.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32526.322 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{8B073608-6451-499D-8D64-713DC2E95196}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Source", "Source\Source.csproj", "{C9DDC481-751D-47DC-AB66-DBC9C8F137E6}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {8B073608-6451-499D-8D64-713DC2E95196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {8B073608-6451-499D-8D64-713DC2E95196}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {8B073608-6451-499D-8D64-713DC2E95196}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {8B073608-6451-499D-8D64-713DC2E95196}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {C9DDC481-751D-47DC-AB66-DBC9C8F137E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {C9DDC481-751D-47DC-AB66-DBC9C8F137E6}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {C9DDC481-751D-47DC-AB66-DBC9C8F137E6}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {C9DDC481-751D-47DC-AB66-DBC9C8F137E6}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {137BD46E-2279-41CB-9EDB-0A467A89BDF4} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /docs/static/hash.md: -------------------------------------------------------------------------------- 1 | # 散列算法 2 | 3 | 散列算法在软件开发中经常被用来校验数据完整性,也会用来对密码等数据进行不可逆加密进行保护;本工具包提供了MD5、SHA1、SHA256、SHA384、SHA512等常用散列算法。 4 | 5 | [MD5散列算法](#hash-md5) 6 | 7 | [SHA1散列算法](#hash-sha1) 8 | 9 | [SHA256散列算法](#hash-sha256) 10 | 11 | [SHA384散列算法](#hash-sha384) 12 | 13 | [SHA512散列算法](#hash-sha512) 14 | 15 | #### 1. MD5散列算法 16 | 17 | ###### public string MD5(string text, string encoding = "utf-8") 18 | 19 | 说明:对传入的字符串进行MD5散列计算,并返回结算结果;编码格式默认为UTF8,可进行指定。 20 | 21 | ```c# 22 | string md5Str = Xmtool.Hash().MD5("admin@123"); 23 | // TODO 24 | ``` 25 | 26 | #### 2. SHA1散列算法 27 | 28 | ###### public string SHA1(string text, string encoding = "utf-8") 29 | 30 | 说明:对传入的字符串进行SHA1散列计算,并返回计算结果;编码格式默认为UTF8,可进行指定。 31 | 32 | ```c# 33 | string sha1Str = Xmtool.Hash().SHA1("admin@123"); 34 | // TODO 35 | ``` 36 | 37 | #### 3. SHA256散列算法 38 | 39 | ###### public string SHA256(string text, string encoding = "utf-8") 40 | 41 | 说明:对传入的字符串进行SHA256散列计算,并返回计算结果;编码格式默认为UTF8,可进行指定。 42 | 43 | ```c# 44 | string sha256Str = Xmtool.Hash().SHA256("admin@123"); 45 | // TODO 46 | ``` 47 | 48 | #### 4. SHA384散列算法 49 | 50 | ###### public string SHA384(string text, string encoding = "utf-8") 51 | 52 | 说明:对传入的字符串进行SHA384散列计算,并返回计算结果;编码格式默认为UTF8,可进行指定。 53 | 54 | ```c# 55 | string sha384Str = Xmtool.Hash().SHA384("admin@123"); 56 | // TODO 57 | ``` 58 | 59 | #### 5. SHA512散列算法 60 | 61 | ###### public string SHA512(string text, string encoding = "utf-8") 62 | 63 | 说明:对传入的字符串进行SHA512散列计算,并返回计算结果;编码格式默认为UTF8,可进行指定。 64 | 65 | ```c# 66 | string sha512Str = Xmtool.Hash().SHA512("admin@123"); 67 | // TODO 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /docs/static/json.md: -------------------------------------------------------------------------------- 1 | # JSON配置文件 2 | 3 | JSON配置文件是基于[DynamicObjectExt](./?item=0212)扩展动态对象封装而成的JSON文件解析工具。通过JSON配置文件工具可以方便的将JSON文件解析成动态对象进行操作;并且支持同时解析多个JSON文件,JSON文件中的同名属性会根据加载顺序进行覆盖。 4 | 5 | 通过JSON配置文件可以将系统中常用到的属性配置、系统设置等文件进行加载解析,在系统中方便的操作;当然,也可以是从其他地方(比如数据库)获取到的合法JSON字符串进行解析。 6 | 7 | 使用时,首先需要获取JSON配置文件工具对象: 8 | 9 | ```c# 10 | JsonTool json = Xmtool.Json(); 11 | // TODO 12 | ``` 13 | 14 | 然后,可以通过其中提供的方法解析JSON文件或JSON字符串: 15 | 16 | [AddJsonFile方法](#addjsonfile) 17 | 18 | [Parse方法](#parse) 19 | 20 | 21 | 22 | #### 1. AddJsonFile方法 23 | 24 | ##### public JsonConfigParser AddJsonFile(string path) 25 | 26 | ###### 说明:增加要解析的JSON配置文件。 27 | 28 | ###### 参数: 29 | 30 | **path**:要解析的JSON配置文件绝对路径。 31 | 32 | 33 | 34 | #### 2. Parse方法 35 | 36 | ##### public dynamic Parse(string jsonStr = null) 37 | 38 | ###### 说明:将通过AddJsonFile方法设置的JSON配置文件,以及参数传入的JSON字符串进行解析,并返回解析后的动态对象。 39 | 40 | ###### 参数: 41 | 42 | **jsonStr**:要解析的JSON字符串内容,可以为空;那么将只解析设置的JSON配置文件内容。 43 | 44 | ```c# 45 | // c:\json1.json 46 | { 47 | "User": { 48 | "Name": "softwaiter", 49 | "Age": 18 50 | } 51 | } 52 | ``` 53 | 54 | ```c# 55 | dynamic obj = Xmtool.Json().AddJsonFile("c:\json1.json").Parse(); 56 | Console.WriteLine(obj.User.Name); // 输出softwaiter 57 | ``` 58 | 59 | 如果是多个JSON配置文件,当文件中存在同名属性时,后面的文件内容将覆盖前面文件内容的属性值。 60 | 61 | ```c# 62 | // c:\json2.json 63 | { 64 | "User": { 65 | "Name": "wangxm" 66 | } 67 | } 68 | ``` 69 | 70 | ```c# 71 | dynamic obj = Xmtool.Json().AddJsonFile("c:\json1.json").AddJsonFile("c:\json2.json").Parse(); 72 | Console.WriteLine(obj.User.Name); // 输出wangxm 73 | ``` 74 | 75 | 当然,也可以不设置JSON配置文件,通过输入字符串内容进行解析。 76 | 77 | ```c# 78 | dynamic obj = Xmtool.Json().Parse("{\"Name\": \"softwaiter\"}"); 79 | Console.WriteLine(obj.Name); // 输出softwaiter 80 | ``` -------------------------------------------------------------------------------- /docs/static/types.md: -------------------------------------------------------------------------------- 1 | # 类型判断 2 | 3 | 根据实际应用中的功能需求,封装了TypeTool类库,其中包含了对类型的判断、克隆等操作;后续会根据使用过程中的需求随时添加。 4 | 5 | 想使用类型相关方法时,我们首先需要通过如下方法取得TypeTool对象实例。 6 | 7 | ```c# 8 | TypeTool tt = Xmtool.Type(); 9 | // TODO 10 | ``` 11 | 12 | 有了TypeTool实例之后,就可以调用实例中各种方法了;具体方法如下: 13 | 14 | [判断是否简单类型](#is-simple) 15 | 16 | [判断是否List类型](#is-list) 17 | 18 | [判断对象是否可复制](#is-cloneable) 19 | 20 | [克隆列表对象](#clone-list) 21 | 22 |
23 | 24 |
25 | 26 | #### 1. 判断是否简单类型 27 | 28 | ##### public bool IsSimpleType(object obj) 29 | 30 | ###### 说明:判断指定对象内容是否为简单类型(值类型或字符串类型)。 31 | 32 | ```c# 33 | String str = "Hello World"; 34 | 35 | TypeTool tt = Xmtool.Type(); 36 | if (tt.IsSimpleType(str)) 37 | { 38 | // TODO 39 | } 40 | else 41 | { 42 | // TODO 43 | } 44 | ``` 45 | 46 | #### 2. 判断是否List类型 47 | 48 | ##### public bool IsList(object obj) 49 | 50 | ###### 说明:判断指定对象是否为泛型列表类型。 51 | 52 | ```c# 53 | List persons = new List(); 54 | 55 | TypeTool tt = Xmtool.Type(); 56 | if (tt.IsList(persons)) 57 | { 58 | // TODO 59 | } 60 | ``` 61 | 62 | #### 3. 判断对象是否可复制 63 | 64 | ##### public bool IsCloneable(object obj) 65 | 66 | ###### 说明:判断对象是否可复制(即是否实现了ICloneable接口) 67 | 68 | ```c# 69 | string str = "Hello World."; 70 | 71 | TypeTool tt = Xmtool.Type(); 72 | if (tt.IsCloneable(str)) 73 | { 74 | // TODO 75 | } 76 | ``` 77 | 78 | #### 4. 克隆列表对象 79 | 80 | ##### public IList CloneList(IList list, bool includeContent = true) 81 | 82 | ###### 说明:复制指定列表对象。 83 | 84 | ###### 参数 85 | 86 | list:待复制的列表对象。 87 | 88 | includeContent :是否复制列表对象中的内容,默认为true;否则只复制列表对象本身。 89 | 90 | ```c# 91 | List persons = new List(); 92 | persons.Add("张三"); 93 | persons.Add("李四"); 94 | 95 | TypeTool tt = Xmtool.Type(); 96 | IList cloneObj = tt.CloneList(persons); 97 | // TODO 98 | ``` -------------------------------------------------------------------------------- /Source/TypeTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | 6 | namespace CodeM.Common.Tools 7 | { 8 | public class TypeTool 9 | { 10 | private static TypeTool sTTool = new TypeTool(); 11 | 12 | private TypeTool() 13 | { 14 | } 15 | 16 | internal static TypeTool New() 17 | { 18 | return sTTool; 19 | } 20 | 21 | /// 22 | /// 判断一个对象是否简单类型(值类型和字符串) 23 | /// 24 | /// 25 | /// 26 | public bool IsSimpleType(object obj) 27 | { 28 | Type _typ = obj.GetType(); 29 | return _typ.IsValueType || _typ == typeof(string); 30 | } 31 | 32 | public bool IsCloneable(object obj) 33 | { 34 | return obj is ICloneable; 35 | } 36 | 37 | public bool IsList(object obj) 38 | { 39 | Type _typ = obj.GetType(); 40 | return _typ.IsGenericType && _typ.GetGenericTypeDefinition() == typeof(List<>); 41 | } 42 | 43 | public IList CloneList(IList list, bool includeContent = true) 44 | { 45 | Type geneType = typeof(List<>); 46 | Type implType = geneType.MakeGenericType(list.GetType().GetGenericArguments()); 47 | ConstructorInfo ci = implType.GetConstructor(new Type[] { }); 48 | IList cloneObj = ci.Invoke(new Object[] { }) as IList; 49 | if (includeContent) 50 | { 51 | foreach (object item in list) 52 | { 53 | cloneObj.Add(item); 54 | } 55 | } 56 | return cloneObj; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Source/RandomTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CodeM.Common.Tools 4 | { 5 | public class RandomTool 6 | { 7 | private static RandomTool sRTool = new RandomTool(); 8 | 9 | private RandomTool() 10 | { 11 | } 12 | 13 | internal static RandomTool New() 14 | { 15 | return sRTool; 16 | } 17 | 18 | private static char[] sCaptchaChars = {'2', '3', '4', '5', '6', '7', '8', '9', 19 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 20 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 21 | 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 22 | 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; 23 | 24 | public string RandomCaptcha(int len, bool onlyNumber = false) 25 | { 26 | if (onlyNumber) 27 | { 28 | string result = string.Empty; 29 | int step = (int)DateTime.Now.Ticks % int.MaxValue; 30 | Random r = new Random(step); 31 | for (int i = 0; i < len; i++) 32 | { 33 | int num = r.Next(0, int.MaxValue) % 10; 34 | result += num; 35 | } 36 | return result; 37 | } 38 | else 39 | { 40 | string result = string.Empty; 41 | int step = (int)DateTime.Now.Ticks % int.MaxValue; 42 | Random r = new Random(step); 43 | for (int i = 0; i < len; i++) 44 | { 45 | int index = r.Next(0, int.MaxValue) % sCaptchaChars.Length; 46 | result += sCaptchaChars[index]; 47 | } 48 | return result; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Source/DynamicObject/DynamicObjectExtMetaObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Dynamic; 3 | using System.Linq.Expressions; 4 | 5 | namespace CodeM.Common.Tools.DynamicObject 6 | { 7 | [Serializable] 8 | internal class DynamicObjectExtMetaObject : DynamicMetaObject 9 | { 10 | DynamicObjectExt mValue; 11 | 12 | public DynamicObjectExtMetaObject(Expression expression, BindingRestrictions restrictions, object value) : 13 | base(expression, restrictions, value) 14 | { 15 | mValue = (DynamicObjectExt)value; 16 | } 17 | 18 | public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) 19 | { 20 | string methodName = "SetValue"; 21 | BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(Expression, LimitType); 22 | Expression[] args = new Expression[2]; 23 | args[0] = Expression.Constant(binder.Name); 24 | args[1] = Expression.Convert(value.Expression, typeof(object)); 25 | Expression self = Expression.Convert(Expression, LimitType); 26 | Expression methodCall = Expression.Call(self, typeof(DynamicObjectExt ).GetMethod(methodName), args); 27 | DynamicMetaObject dmoSetValue = new DynamicMetaObject(methodCall, restrictions); 28 | return dmoSetValue; 29 | } 30 | 31 | public override DynamicMetaObject BindGetMember(GetMemberBinder binder) 32 | { 33 | string methodName = "GetValue"; 34 | BindingRestrictions restrictions = BindingRestrictions.GetTypeRestriction(Expression, LimitType); 35 | Expression[] args = new Expression[1]; 36 | args[0] = Expression.Constant(binder.Name); 37 | Expression self = Expression.Convert(Expression, LimitType); 38 | Expression methodCall = Expression.Call(self, typeof(DynamicObjectExt).GetMethod(methodName), args); 39 | DynamicMetaObject dmoGetValue = new DynamicMetaObject(methodCall, restrictions); 40 | return dmoGetValue; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Test/resources/ioc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | "wangxm" 6 | 7 | 8 | 9 | "softwaiter" 10 | true 11 | 12 | 13 | 14 | "xiaoming" 15 | 18 16 | true 17 | 18 | 19 | 20 | "mingming" 21 | Female 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 | 18 65 | true 66 | 67 | 68 | -------------------------------------------------------------------------------- /docs/static/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "subPath": "/Xmtool", 3 | "title": "Xmtool", 4 | "topicWidth": 250, 5 | "openLevel": 1, 6 | "topics": [ 7 | { 8 | "id": "01", 9 | "name": "Xmtool是什么?", 10 | "src": "static/what.md" 11 | }, 12 | { 13 | "id": "02", 14 | "name": "开始使用", 15 | "submenus": [ 16 | { 17 | "id": "0201", 18 | "name": "日期时间", 19 | "src": "static/datetime.md" 20 | }, 21 | { 22 | "id": "0202", 23 | "name": "正则表达式", 24 | "src": "static/regex.md" 25 | }, 26 | { 27 | "id": "0203", 28 | "name": "加密解密", 29 | "src": "static/crypto.md" 30 | }, 31 | { 32 | "id": "0204", 33 | "name": "散列算法", 34 | "src": "static/hash.md" 35 | }, 36 | { 37 | "id": "0205", 38 | "name": "随机值", 39 | "src": "static/random.md" 40 | }, 41 | { 42 | "id": "0206", 43 | "name": "发送邮件", 44 | "src": "static/sendmail.md" 45 | }, 46 | { 47 | "id": "0207", 48 | "name": "发送短信", 49 | "src": "static/sendsms.md" 50 | }, 51 | { 52 | "id": "0208", 53 | "name": "类型判断", 54 | "src": "static/types.md" 55 | }, 56 | { 57 | "id": "0209", 58 | "name": "XML读取", 59 | "src": "static/xml.md" 60 | }, 61 | { 62 | "id": "0210", 63 | "name": "Web操作", 64 | "src": "static/web.md" 65 | }, 66 | { 67 | "id": "0211", 68 | "name": "图形验证码", 69 | "src": "static/captcha.md" 70 | }, 71 | { 72 | "id": "0212", 73 | "name": "扩展动态对象", 74 | "src": "static/dynamicobj.md" 75 | }, 76 | { 77 | "id": "0213", 78 | "name": "JSON配置文件", 79 | "src": "static/json.md" 80 | }, 81 | { 82 | "id": "0214", 83 | "name": "图片处理", 84 | "src": "static/image.md" 85 | }, 86 | { 87 | "id": "0215", 88 | "name": "OSS文件上传", 89 | "src": "static/oss.md" 90 | } 91 | ] 92 | } 93 | ] 94 | } -------------------------------------------------------------------------------- /Source/Xmtool.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools.Captcha; 2 | using CodeM.Common.Tools.DynamicObject; 3 | using CodeM.Common.Tools.Json; 4 | using CodeM.Common.Tools.Oss; 5 | using CodeM.Common.Tools.Sms; 6 | using CodeM.Common.Tools.Web; 7 | using CodeM.Common.Tools.Xml; 8 | 9 | namespace CodeM.Common.Tools 10 | { 11 | public class Xmtool 12 | { 13 | public static DynamicObjectExt DynamicObject() 14 | { 15 | return new DynamicObjectExt(); 16 | } 17 | 18 | public static JsonTool Json 19 | { 20 | get 21 | { 22 | return JsonTool.New(); 23 | } 24 | } 25 | 26 | public static WebTool Web 27 | { 28 | get 29 | { 30 | return WebTool.New(); 31 | } 32 | } 33 | 34 | public static DateTimeTool DateTime() 35 | { 36 | return DateTimeTool.New(); 37 | } 38 | 39 | public static CryptoTool Crypto() 40 | { 41 | return CryptoTool.New(); 42 | } 43 | 44 | public static HashTool Hash() 45 | { 46 | return HashTool.New(); 47 | } 48 | 49 | public static RegexTool Regex() 50 | { 51 | return RegexTool.New(); 52 | } 53 | 54 | public static TypeTool Type() 55 | { 56 | return TypeTool.New(); 57 | } 58 | 59 | public static XmlTool Xml() 60 | { 61 | return XmlTool.New(); 62 | } 63 | 64 | public static MailTool Mail(string host, int port, string account, string password, bool enableSsl = false) 65 | { 66 | return MailTool.New(host, port, enableSsl, account, password); 67 | } 68 | 69 | public static RandomTool Random() 70 | { 71 | return RandomTool.New(); 72 | } 73 | 74 | public static ICaptcha Captcha(CaptchaKind kind) 75 | { 76 | return CaptchaTool.New(kind); 77 | } 78 | 79 | public static ISmsProvider Sms(SmsProvider provider) 80 | { 81 | return SmsTool.New(provider); 82 | } 83 | 84 | public static IOssProvider Oss(OssProvider provider) 85 | { 86 | return OssTool.New(provider); 87 | } 88 | 89 | public static ImageTool Image() 90 | { 91 | return ImageTool.New(); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /docs/static/sendmail.md: -------------------------------------------------------------------------------- 1 | # 发送邮件 2 | 3 | 发送邮件常用来作为发送系统通知的一种方式,广泛的在各种后台管理中使用;虽然.NetCore框架提供了发送邮件的组件,但使用起来还是有一点复杂度,为了使用起来更简单、更友好,对发送邮件的功能进行了二次封装。 4 | 5 | 首先,需要获得一个邮件发送对象;在获取该对象时,必须传递最基本的SMTP邮件服务器地址、SMTP端口、是否启用SSL,以及发送邮件使用的账户名和密码。 6 | 7 | [获取邮件发送对象](#create-mailtool) 8 | 9 | 获取到邮件发送对象之后,可以直接调用下面的任意一个方法进行邮件发送操作,简单方便。 10 | 11 | [发送普通邮件-完全版](#send-all) 12 | 13 | [发送普通邮件-简化版](#send-simple) 14 | 15 | [发送网页邮件-完全版](#sendhtml-all) 16 | 17 | [发送网页邮件-简化版](#sendhtml-simple) 18 | 19 | 20 | 21 | #### 1. 获取邮件发送对象 22 | 23 | ###### public static MailTool Mail(string host, int port, string account, string password, bool enableSsl = false) 24 | 25 | ```c# 26 | MailTool mail = Xmtool.Mail("smtp.126.com", 25, "test", "test@123"); 27 | // TODO 28 | ``` 29 | 30 | #### 2. 发送普通邮件-完全版 31 | 32 | ###### public void Send(string subject, string body, string bodyEncoding, string from, string fromName, string to, string replyTo, string cc, string bcc, params string[] attachments) 33 | 34 | ```c# 35 | MailTool mail = Xmtool.Mail("smtp.126.com", 25, "test", "test@123"); 36 | mail.Send("邮件标题", "邮件内容", "utf-8(内容编码格式)", "收件人看到的发件人邮箱地址", 37 | "收件人看到的发件人名称", "收件人邮箱地址", "收件人回复邮件的接收地址", 38 | "抄送地址,多个用;分隔", "秘密抄送地址,多个用;分隔", "附件文件地址,可以多个"); 39 | ``` 40 | 41 | #### 3. 发送普通邮件-简化版 42 | 43 | ###### public void SimpleSend(string subject, string body, string from, string to, params string[] attachments) 44 | 45 | ```c# 46 | MailTool mail = Xmtool.Mail("smtp.126.com", 25, "test", "test@123"); 47 | mail.SimpleSend("邮件标题", "邮件内容", "收件人看到的发件人邮箱地址", "收件人邮箱地址", "附件文件地址"); 48 | ``` 49 | 50 | #### 4. 发送网页邮件-完全版 51 | 52 | ###### public void SendHtml(string subject, string body, string bodyEncoding, string from, string fromName, string to, string replyTo, string cc, string bcc, params string[] attachments) 53 | 54 | ```c# 55 | MailTool mail = Xmtool.Mail("smtp.126.com", 25, "test", "test@123"); 56 | mail.Send("邮件标题", "网页源码内容", "utf-8(内容编码格式)", "收件人看到的发件人邮箱地址", 57 | "收件人看到的发件人名称", "收件人邮箱地址", "收件人回复邮件的接收地址", 58 | "抄送地址,多个用;分隔", "秘密抄送地址,多个用;分隔", "附件文件地址,可以多个"); 59 | ``` 60 | 61 | #### 5. 发送网页邮件-简化版 62 | 63 | ###### public void SimpleSendHtml(string subject, string body, string from, string to, params string[] attachments) 64 | 65 | ```c# 66 | MailTool mail = Xmtool.Mail("smtp.126.com", 25, "test", "test@123"); 67 | mail.Send("邮件标题", "网页源码内容", "收件人看到的发件人邮箱地址", "收件人邮箱地址", "附件文件地址"); 68 | ``` 69 | 70 | 71 | 72 | *另外,同时提供了SendAsync、SendHtmlAsync等功能相同的异步方法,使用时可根据需要选择。 73 | 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 |

5 | 一个简单易用的.Net工具类库(持续集成中...) 6 |

7 |
8 |
9 | 10 | 11 | ## :beginner: 简介 12 | 13 | Xmtool是一个基于.Net的常用功能集成工具类库,目的是做成一个像Java语言中的Hutool类似的工具库,将和具体业务逻辑无关的常用功能进行抽象和封装,集成到一个类库中,方便使用维护,提升开发效率。 14 | 15 | 16 | ## :rocket: 版本 17 | **.NetCore3.1**:3.0.0之前的版本全部基于.netcore3.1开发;后续所有变更在netcore3.1分支进行。 18 |
19 | **.Net8.0**:从3.0.0开始之后的版本,全部基于.net8开发;后续所有变更在master分支进行。 20 | 21 | ## :package:安装 22 | 23 | ##### Package Manager 24 | 25 | ```shell 26 | Install-Package Xmtool -Version 3.0.0 27 | ``` 28 | 29 | ##### .NET CLI 30 | 31 | ```shell 32 | dotnet add package Xmtool --version 3.0.0 33 | ``` 34 | 35 | ##### PackageReference 36 | 37 | ```xml 38 | 39 | ``` 40 | 41 | ##### Paket CLI 42 | 43 | ```shell 44 | paket add Xmtool --version 3.0.0 45 | ``` 46 | 47 | 48 | 49 | ## :hammer_and_wrench:使用说明 50 | 51 | Xmtool为了方便调用,将所有功能统一封装集成到静态类Xmtool中,在调用相应方法时,全部以Xmtool为入口,根据方法所属功能分类逐级调用即可;同时在一定程度上支持了链式调用,大大提升了使用便利性,也使代码看起来更加优雅。 52 | 53 | ###### 例:生成一个4位的数字短信验证码。 54 | 55 | ```c# 56 | public string GetSmsCode() 57 | { 58 | string code = Xmtool.Random().RandomCaptcha(4, true); 59 | return code; 60 | } 61 | ``` 62 | 63 | ###### 例:判断字符串是否有效手机号码 64 | 65 | ```c# 66 | public bool IsMobile(string str) 67 | { 68 | return Xmtool.Regex().IsMobile(str); 69 | } 70 | ``` 71 | 72 | 73 | 74 | ## :pencil:文档 75 | 76 | - [日期时间](https://softwaiter.github.io/Xmtool/?item=0201) 77 | - [正则表达式](https://softwaiter.github.io/Xmtool/?item=0202) 78 | - [加密解密](https://softwaiter.github.io/Xmtool/?item=0203) 79 | - [散列算法](https://softwaiter.github.io/Xmtool/?item=0204) 80 | - [随机值](https://softwaiter.github.io/Xmtool/?item=0205) 81 | - [发送邮件](https://softwaiter.github.io/Xmtool/?item=0206) 82 | - [发送短信](https://softwaiter.github.io/Xmtool/?item=0207) 83 | - [类型判断](https://softwaiter.github.io/Xmtool/?item=0208) 84 | - [XML读取](https://softwaiter.github.io/Xmtool/?item=0209) 85 | - [Web操作](https://softwaiter.github.io/Xmtool/?item=0210) 86 | - [图形验证码](https://softwaiter.github.io/Xmtool/?item=0211) 87 | - [扩展动态对象](https://softwaiter.github.io/Xmtool/?item=0212) 88 | - [JSON配置文件](https://softwaiter.github.io/Xmtool/?item=0213) 89 | - [图片处理](https://softwaiter.github.io/Xmtool/?item=0214) 90 | - [OSS文件上传](https://softwaiter.github.io/Xmtool/?item=0215) 91 | 92 | 93 | 94 | # 🎈 协议 95 | 96 | Xmtool 使用 [MIT 协议](https://github.com/softwaiter/Xmtool/blob/master/LICENSE) 97 | -------------------------------------------------------------------------------- /docs/static/oss.md: -------------------------------------------------------------------------------- 1 | # OSS文件上传 2 | 3 | 将本地文件上传到服务器是软件系统经常会遇到的需求,例如:设置用户头像,上传Excel报表等等;涉及到网络访问性能、存储空间等因素的考虑,通常我们会选择使用第三方的对象存储服务,本类库将比较常用的第三方对象存储服务进行了封装整合,让用户能够使用一套API将文件上传到不同的对象存储服务上,方便了用户使用。 4 | 5 | 目前,类库支持了七牛、阿里云、腾讯3种对象存储服务。 6 | 7 | ```c# 8 | public enum OssProvider 9 | { 10 | Unset, 11 | Qiniu, // 七牛 12 | Alibaba, // 阿里云 13 | Tencent // 腾讯云 14 | } 15 | ``` 16 | 17 | 在使用过程中,根据需要使用的OSS存储服务获取OSS对象,即可调用方法进行文件上传,下面将逐步说明。 18 | 19 | ## 一、获取OSS对象 20 | 21 | 首先,根据我们准备使用的OSS存储服务类型,获取对应的OSS操作对象。 22 | 23 | ```c# 24 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 25 | // TODO 26 | ``` 27 | 28 | ## 二、初始化配置 29 | 30 | OSS操作对象,必须进行初始化配置才能进行文件上传操作,不同的存储服务类型配置参数略有不同,下面将一一说明。 31 | 32 | ### 1. 七牛存储服务初始化配置 33 | 34 | ```c# 35 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 36 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址"); 37 | // TODO 38 | ``` 39 | 40 | ### 2.阿里云存储服务初始化配置 41 | 42 | ```c# 43 | IOssProvider oss = Xmtool.Oss(OssProvider.Alibaba); 44 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址", "替换成存储桶对应的EndPoint地址"); 45 | // TODO 46 | ``` 47 | 48 | ### 3.腾讯云存储服务初始化配置 49 | 50 | ```c# 51 | IOssProvider oss = Xmtool.Oss(OssProvider.Tencent); 52 | oss.Config("替换成自己的AppId", "替换成自己的SecretId", "替换成自己的SecretKey", "替换成自己的域名地址", "替换成存储桶对应的Region简称"); 53 | // TODO 54 | ``` 55 | 56 | ## 三、上传本地文件 57 | 58 | 经过上一步的初始化配制后,就可以进行文件上传操作了;类库支持文件路径和文件流两种上传方式。 59 | 60 | 通过文件路径上传,方法如下: 61 | 62 | ```c# 63 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 64 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址"); 65 | string url = oss.UploadFile("替换成自己的存储桶名称", "要上传的本地文件路径", "上传到服务器的文件key,如果不传将随机生成"); 66 | // 返回的url即是上传成功后的文件访问地址,是否可公开访问根据存储桶的访问权限设定。 67 | // TODO 68 | ``` 69 | 70 | ## 四、上传文件流 71 | 72 | 通过文件流上传,方法如下: 73 | 74 | ```c# 75 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 76 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址"); 77 | using (FileStream stream = new FileStream("要上传的本地文件路径", FileMode.Open)) 78 | { 79 | string url = oss.UploadStream("替换成自己的存储桶名称", stream, "上传到服务器的文件key,如果不传将随机生成"); 80 | // TODO 81 | } 82 | ``` 83 | 84 | ## 五、设置上传文件ContentType 85 | 86 | 在上传文件时,如果不指定ContentType,除七牛会自动判断上传文件类型外,阿里云和腾讯云都会将文件默认成二进制流文件,这在后面的访问过程中会影响文件的预览等操作。因此,我们可以在上传时明确指定文件的类型。 87 | 88 | ```c# 89 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 90 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址"); 91 | string url = oss.SetContentType("image/png") 92 | .UploadFile("替换成自己的存储桶名称", "要上传的本地文件路径", "上传到服务器的文件key,如果不传将随机生成"); 93 | // TODO 94 | ``` 95 | 96 | ## 六、是否使用HTTPS 97 | 98 | ```c# 99 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu); 100 | oss.Config("替换成自己的AppKey", "替换成自己的AppSecret", "替换成自己的域名地址"); 101 | oss.SetUseHttps(true); 102 | // TODO 103 | ``` 104 | 105 | -------------------------------------------------------------------------------- /Source/HashTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | using System.Text; 4 | 5 | namespace CodeM.Common.Tools 6 | { 7 | public class HashTool 8 | { 9 | private static HashTool sHG = new HashTool(); 10 | 11 | private HashTool() 12 | { 13 | } 14 | 15 | internal static HashTool New() 16 | { 17 | return sHG; 18 | } 19 | 20 | public string MD5(string text, string encoding = "utf-8") { 21 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 22 | 23 | using (MD5 md5 = System.Security.Cryptography.MD5.Create()) { 24 | md5.ComputeHash(bytes); 25 | byte[] hashBytes = md5.Hash; 26 | md5.Clear(); 27 | return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 28 | } 29 | } 30 | 31 | public string SHA1(string text, string encoding = "utf-8") { 32 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 33 | 34 | using (SHA1 sha1 = System.Security.Cryptography.SHA1.Create()) { 35 | sha1.ComputeHash(bytes); 36 | byte[] hashBytes = sha1.Hash; 37 | sha1.Clear(); 38 | return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 39 | } 40 | } 41 | 42 | public string SHA256(string text, string encoding = "utf-8") { 43 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 44 | 45 | using (SHA256 sha256 = System.Security.Cryptography.SHA256.Create()) { 46 | sha256.ComputeHash(bytes); 47 | byte[] hashBytes = sha256.Hash; 48 | sha256.Clear(); 49 | return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 50 | } 51 | } 52 | 53 | public string SHA384(string text, string encoding = "utf-8") { 54 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 55 | 56 | using (SHA384 sha384 = System.Security.Cryptography.SHA384.Create()) { 57 | sha384.ComputeHash(bytes); 58 | byte[] hashBytes = sha384.Hash; 59 | sha384.Clear(); 60 | return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 61 | } 62 | } 63 | 64 | public string SHA512(string text, string encoding = "utf-8") { 65 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 66 | 67 | using (SHA512 sha512 = System.Security.Cryptography.SHA512.Create()) { 68 | sha512.ComputeHash(bytes); 69 | byte[] hashBytes = sha512.Hash; 70 | sha512.Clear(); 71 | return BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /docs/static/sendsms.md: -------------------------------------------------------------------------------- 1 | # 发送短信 2 | 3 | 发送短信是现在软件系统中必不可少的功能;无论是短信验证码登录,还是系统消息通知,以及忘记密码等场景,都需要发送短信来配合完成。市面上有各种各样的短信发送平台,各个平台都提供了相应的SDK工具包或者HTTP接口,使用起来需要熟悉各个平台不同的SDK方法和HTTP接口参数等等,使用起来很不方便;系统运行上线后如果想切换一个短信发送平台,更是困难,相当于重新实现一次短信发送功能。 4 | 5 | 为了解决以上问题,本类库定义了一套标准方法,将各种短信发送平台基于标准方法进行二次封装;在使用时,无论是选用哪家的短信发送平台,都通过标准方法进行调用,使用方便,扩展维护也异常简单。 6 | 7 | 当前版本,系统实现了阿里短信和腾讯短信两个短信发送平台的二次封装,后续根据需要会持续更新。 8 | 9 | ```c# 10 | public enum SmsProvider 11 | { 12 | Unset, 13 | Alibaba, // 阿里短信平台 14 | Tencent // 腾讯短信平台 15 | } 16 | ``` 17 | 18 | 使用时,需要首先获取一个短信发送对象ISmsProvider;获取对象时,需要指定短信发送平台。 19 | 20 | [获取短信发送对象](#create-smstool) 21 | 22 | 获取短信发送对象后,需要使用Config方法进行配置,这是正式发送短信前必须要进行的工作。 23 | 24 | [配置短信发送对象](#config-smstool) 25 | 26 | 配置完成后,用户便可以调用下面的任意一个方法进行短信发送操作,简单方便。 27 | 28 | [发送短信-标准版](#send-standard) 29 | 30 | [发送短信-自定义版](#send-cutomized) 31 | 32 | 33 | 34 | #### 1. 获取短信发送对象 35 | 36 | ###### public static ISmsProvider Sms(SmsProvider provider) 37 | 38 | ```c# 39 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Alibaba); 40 | // TODO 41 | ``` 42 | 43 | #### 2. 配置短信发送对象 44 | 45 | ###### public static ISmsProvider Config(params string[] args) 46 | 47 | ```c# 48 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Alibaba); 49 | 50 | // 阿里云短行平台配置方法 51 | sms = sms.Config("accessKeyId(替换成自己的)", "accessKeySecret(替换成自己的)", 52 | "阿里云短信签名(替换成自己的)", "模板编码(替换成自己的)"); 53 | /* 54 | sms = sms.Config("secretId(替换成自己的)", "secretKey(替换成自己的)", 55 | "腾讯云短信签名(替换成自己的)", "模板Id(替换成自己的)", "appId(替换成自己的)"); 56 | */ 57 | 58 | // TODO 59 | ``` 60 | 61 | #### 3. 发送短信-标准版 62 | 63 | ###### 说明:标准版默认使用配置时指定的签名和模板进行发送。 64 | 65 | ###### public bool Send(string templateParam, params string[] phoneNums) 66 | 67 | ```c# 68 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Alibaba); 69 | 70 | // 阿里云短行平台配置方法 71 | sms = sms.Config("accessKeyId(替换成自己的)", "accessKeySecret(替换成自己的)", 72 | "阿里云短信签名(替换成自己的)", "模板编码(替换成自己的)"); 73 | /* 74 | sms = sms.Config("secretId(替换成自己的)", "secretKey(替换成自己的)", 75 | "腾讯云短信签名(替换成自己的)", "模板Id(替换成自己的)", "appId(替换成自己的)"); 76 | */ 77 | 78 | sms.Send("参数(替换成自己的,如:{\"code\":\"1234\"})", "136********"); 79 | ``` 80 | 81 | #### 4. 发送短信-自定义版 82 | 83 | ###### 说明:自定义版可以在发送时指定签名和模板。 84 | 85 | ###### public bool Send2(string signName, string templateCode, string templateParam, params string[] phoneNums) 86 | 87 | ```c# 88 | ISmsProvider sms = Xmtool.Sms(SmsProvider.Alibaba); 89 | 90 | // 阿里云短行平台配置方法 91 | sms = sms.Config("accessKeyId(替换成自己的)", "accessKeySecret(替换成自己的)", 92 | "阿里云短信签名(替换成自己的)", "模板编码(替换成自己的)"); 93 | /* 94 | sms = sms.Config("secretId(替换成自己的)", "secretKey(替换成自己的)", 95 | "腾讯云短信签名(替换成自己的)", "模板Id(替换成自己的)", "appId(替换成自己的)"); 96 | */ 97 | 98 | sms.Send("自定义签名", "自定义模板", "参数(替换成自己的,如:1234)", "136********"); 99 | ``` 100 | 101 | *另外,同时提供了SendAsync、Send2Async等功能相同的异步方法,使用时可根据需要选择。 -------------------------------------------------------------------------------- /Test/OssTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using System.IO; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Test 7 | { 8 | public class OssTest 9 | { 10 | private ITestOutputHelper output; 11 | 12 | public OssTest(ITestOutputHelper output) 13 | { 14 | this.output = output; 15 | } 16 | 17 | [Fact] 18 | public void QiniuUploadFile() 19 | { 20 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu) 21 | .Config("替换成你自己的AppKey", "替换成你自己的AppSecret", "替换成自己的域名地址"); 22 | string url = oss.UploadFile("替换成你的存储桶名称", "要上传的本地文件路径", "上传到服务器的文件key,如果不传将随机生成"); 23 | Assert.NotEmpty(url); 24 | } 25 | 26 | [Fact] 27 | public void QiniuUploadStream() 28 | { 29 | IOssProvider oss = Xmtool.Oss(OssProvider.Qiniu) 30 | .Config("替换成你自己的AppKey", "替换成你自己的AppSecret", "替换成自己的域名地址"); 31 | using (FileStream stream = new FileStream("要上传的本地文件路径", FileMode.Open)) 32 | { 33 | string url = oss.UploadStream("替换成你的存储桶名称", stream, "上传到服务器的文件key,如果不传将随机生成"); 34 | Assert.NotEmpty(url); 35 | } 36 | } 37 | 38 | [Fact] 39 | public void AlibabaUploadFile() 40 | { 41 | IOssProvider oss = Xmtool.Oss(OssProvider.Alibaba) 42 | .Config("替换成你自己的AppKey", "替换成你自己的AppSecret", "替换成自己的域名地址", "替换成存储桶对应的EndPoint地址"); 43 | string url = oss.UploadFile("替换成你的存储桶名称", "要上传的本地文件路径", "上传到服务器的文件key,如果不传将随机生成"); 44 | Assert.NotEmpty(url); 45 | } 46 | 47 | [Fact] 48 | public void AlibabaUploadStream() 49 | { 50 | IOssProvider oss = Xmtool.Oss(OssProvider.Alibaba) 51 | .Config("替换成你自己的AppKey", "替换成你自己的AppSecret", "替换成自己的域名地址", "替换成存储桶对应的EndPoint地址"); 52 | using (FileStream stream = new FileStream("要上传的本地文件路径", FileMode.Open)) 53 | { 54 | string url = oss.UploadStream("替换成你的存储桶名称", stream, "上传到服务器的文件key,如果不传将随机生成"); 55 | Assert.NotEmpty(url); 56 | } 57 | } 58 | 59 | [Fact] 60 | public void TencentUploadFile() 61 | { 62 | IOssProvider oss = Xmtool.Oss(OssProvider.Tencent) 63 | .Config("替换成你自己的AppId", "替换成你自己的SecretId", "替换成你自己的SecretKey", "替换成自己的域名地址", "替换成存储桶对应的Region简称"); 64 | string url = oss.UploadFile("替换成你的存储桶名称", "要上传的本地文件路径", "上传到服务器的文件key,如果不传将随机生成"); 65 | Assert.NotEmpty(url); 66 | } 67 | 68 | [Fact] 69 | public void TencentUploadStream() 70 | { 71 | IOssProvider oss = Xmtool.Oss(OssProvider.Tencent) 72 | .Config("替换成你自己的AppId", "替换成你自己的SecretId", "替换成你自己的SecretKey", "替换成自己的域名地址", "替换成存储桶对应的Region简称"); 73 | using (FileStream stream = new FileStream("要上传的本地文件路径", FileMode.Open)) 74 | { 75 | string url = oss.UploadStream("替换成你的存储桶名称", stream, "上传到服务器的文件key,如果不传将随机生成"); 76 | Assert.NotEmpty(url); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Test/Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | PreserveNewest 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | PreserveNewest 43 | 44 | 45 | PreserveNewest 46 | 47 | 48 | PreserveNewest 49 | 50 | 51 | PreserveNewest 52 | 53 | 54 | PreserveNewest 55 | 56 | 57 | PreserveNewest 58 | 59 | 60 | PreserveNewest 61 | 62 | 63 | PreserveNewest 64 | 65 | 66 | PreserveNewest 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /docs/static/datetime.md: -------------------------------------------------------------------------------- 1 | # 日期时间 2 | 3 | DateTimeTool是Xmtool中用来提供日期时间相关方法的工具类,使用时可通过Xmtool下的`DateTime`方法获得。 4 | 5 | ```c# 6 | DateTimeTool dtt = Xmtool.DateTime(); 7 | ``` 8 | 9 | 目前该工具类下主要提供了时间戳、字符串时间范围相关的方法,具体如下: 10 | 11 | [获取10位UTC时间戳](#m1) 12 | 13 | [获取13位UTC时间戳](#m2) 14 | 15 | [根据10位UTC时间戳逆向获得UTC日期时间](#m3) 16 | 17 | [根据13位UTC时间戳逆向获得UTC日期时间](#m4) 18 | 19 | [根据10位UTC时间戳逆向获得本地日期时间](#m5) 20 | 21 | [根据13位UTC时间戳逆向获得本地日期时间](#m6) 22 | 23 | [将字符串表示的时间范围转换为TimSpan时间段](#m7) 24 | 25 | [检查字符串表示的时间范围格式是否合法](#m8) 26 | 27 | 28 | 29 | #### 1. 获取10位UTC时间戳 30 | 31 | ###### public long GetUtcTimestamp10() 32 | 33 | ```c# 34 | // 返回当前UTC时间的10位时间戳 35 | long ts = Xmtool.DateTime().GetUtcTimestamp10(); 36 | ``` 37 | 38 | 39 | 40 | #### 2. 获取13位UTC时间戳 41 | 42 | ###### public long GetUtcTimestamp13() 43 | 44 | ```c# 45 | // 返回当前UTC时间的13位时间戳 46 | long ts = Xmtool.DateTime().GetUtcTimestamp13(); 47 | ``` 48 | 49 | 50 | 51 | #### 3. 根据10位UTC时间戳逆向获得UTC日期时间 52 | 53 | ###### public DateTime GetUtcDateTimeFromUtcTimestamp10(long ts) 54 | 55 | ```c# 56 | long ts = 1660737444; 57 | // 将传入的10位UTC时间戳ts转换为对应的UTC日期时间 58 | DateTime dt = Xmtool.DateTime().GetUtcDateTimeFromUtcTimestamp10(ts); 59 | ``` 60 | 61 | 62 | 63 | #### 4. 根据13位UTC时间戳逆向获得UTC日期时间 64 | 65 | ###### public DateTime GetUtcDateTimeFromUtcTimestamp13(long ts) 66 | 67 | ```c# 68 | long ts = 1660737467850; 69 | // 将传入的13位UTC时间戳ts转换为对应的UTC日期时间 70 | DateTime dt = Xmtool.DateTime().GetUtcDateTimeFromUtcTimestamp13(ts); 71 | ``` 72 | 73 | 74 | 75 | #### 5. 根据10位UTC时间戳逆向获得本地日期时间 76 | 77 | ###### public DateTime GetLocalDateTimeFromUtcTimestamp10(long ts) 78 | 79 | ```c# 80 | long ts = 1660737444; 81 | // 将传入的10位UTC时间戳ts转换为对应的本地化日期时间 82 | DateTime dt = Xmtool.DateTime().GetLocalDateTimeFromUtcTimestamp10(ts); 83 | ``` 84 | 85 | 86 | 87 | #### 6. 根据13位UTC时间戳逆向获得本地日期时间 88 | 89 | ###### public DateTime GetLocalDateTimeFromUtcTimestamp13(long ts) 90 | 91 | ```c# 92 | long ts = 1660737467850; 93 | // 将传入的13位UTC时间戳ts转换为对应的本地化日期时间 94 | DateTime dt = Xmtool.DateTime().GetLocalDateTimeFromUtcTimestamp13(ts); 95 | ``` 96 | 97 | 98 | 99 | #### 7. 将字符串表示的时间范围转换为TimSpan时间段 100 | 101 | ###### public TimeSpan? GetTimeSpanFromString(string timespan, bool throwError = true) 102 | 103 | ###### 参数说明: 104 | 105 | timespan: 时间段的字符表示,支持ms(毫秒)、s(秒)、m(分钟)、h(小时)、d(天);例如:60s表示60秒钟。 106 | 107 | throwError: 转换出错时是否抛出,默认true,直接抛出错误。 108 | 109 | ```c# 110 | string time = "20m"; 111 | // 将传入的字符串表示时间范围转换为TimeSpan时间段,通常用于解析配置文件中的超时时间等 112 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(time); 113 | ``` 114 | 115 | 116 | 117 | #### 8. 检查字符串表示的时间范围格式是否合法 118 | 119 | ###### public bool CheckStringTimeSpan(string timespan, bool throwError = true) 120 | 121 | ###### 参数说明: 122 | 123 | timespan: 时间段的字符表示,支持ms(毫秒)、s(秒)、m(分钟)、h(小时)、d(天);例如:60s表示60秒钟。 124 | 125 | throwError: 转换出错时是否抛出,默认true,直接抛出错误。 126 | 127 | ```c# 128 | string time = "20m"; 129 | // 判断传入的字符串表示时间范围是否为合法的时间段格式,配合GetTimeSpanFromString方法使用,提前处理错误 130 | if (Xmtool.DateTime().CheckStringTimeSpan(time, false)) 131 | { 132 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(time); 133 | } 134 | else 135 | { 136 | Console.WriteLine("输入的字符串时间范围无法识别,请检查格式是否合法。"); 137 | } 138 | ``` 139 | 140 | -------------------------------------------------------------------------------- /Test/ImageTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using SkiaSharp; 3 | using System.ComponentModel; 4 | using System.IO; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | using static System.Net.Mime.MediaTypeNames; 8 | 9 | namespace Test 10 | { 11 | public class ImageTest 12 | { 13 | private ITestOutputHelper output; 14 | 15 | public ImageTest(ITestOutputHelper output) 16 | { 17 | this.output = output; 18 | } 19 | 20 | [Fact] 21 | public void CroppingImageFile() 22 | { 23 | SKImage image = Xmtool.Image().Cropping("e:\\picture\\index.png", new SKRect(300, 300, 800, 800), 300, 300); 24 | Assert.NotNull(image); 25 | 26 | using (FileStream fs = new FileStream("e:\\picture\\index_cropping2.png", FileMode.Create, FileAccess.Write)) 27 | { 28 | image.Encode().SaveTo(fs); 29 | } 30 | } 31 | 32 | [Fact] 33 | public void ResizeImageFile() 34 | { 35 | SKImage image = Xmtool.Image().Resize("e:\\picture\\index.png", 300, 100, false, false); 36 | Assert.NotNull(image); 37 | 38 | using (FileStream fs = new FileStream("e:\\picture\\index_resize2.png", FileMode.Create, FileAccess.Write)) 39 | { 40 | image.Encode().SaveTo(fs); 41 | } 42 | } 43 | 44 | [Fact] 45 | [Description("保持纵横比改变图片大小")] 46 | public void ResizeImageFile2() 47 | { 48 | SKImage image = Xmtool.Image().Resize("e:\\picture\\index.png", 300, 100, true, false); 49 | Assert.NotNull(image); 50 | 51 | using (FileStream fs = new FileStream("e:\\picture\\index_resize3.png", FileMode.Create, FileAccess.Write)) 52 | { 53 | image.Encode().SaveTo(fs); 54 | } 55 | } 56 | 57 | [Fact] 58 | [Description("保持纵横比改变图片大小并居中绘制")] 59 | public void ResizeImageFile3() 60 | { 61 | using (FileStream stream = new FileStream("e:\\picture\\index.png", FileMode.Open, FileAccess.Read, FileShare.Read)) 62 | { 63 | SKImage origin = SKImage.FromEncodedData(stream); 64 | SKImage image = Xmtool.Image().Resize(origin, 300, 100, true, true); 65 | Assert.NotNull(image); 66 | 67 | using (FileStream fs = new FileStream("e:\\picture\\index_resize4.png", FileMode.Create, FileAccess.Write)) 68 | { 69 | image.Encode().SaveTo(fs); 70 | } 71 | } 72 | } 73 | 74 | [Fact] 75 | public void ImageFileToBase64() 76 | { 77 | string base64Data = Xmtool.Image().ToBase64("e:\\picture\\Xmtool.png"); 78 | Assert.NotEmpty(base64Data); 79 | } 80 | 81 | [Fact] 82 | public void ImageStreamToBase64() 83 | { 84 | using (FileStream stream = new FileStream("e:\\picture\\Xmtool.png", FileMode.Open, FileAccess.Read)) 85 | { 86 | string base64Data = Xmtool.Image().ToBase64(stream); 87 | Assert.NotEmpty(base64Data); 88 | } 89 | } 90 | 91 | [Fact] 92 | public void ImageObjectToBase64() 93 | { 94 | SKImage image = SKImage.FromEncodedData("e:\\picture\\Xmtool.png"); 95 | string base64Data = Xmtool.Image().ToBase64(image); 96 | Assert.NotEmpty(base64Data); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Source/Source.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Library 5 | net8.0 6 | 7 | 8 | Xmtool 9 | CodeM.Common.Tools 10 | false 11 | 3.0.0 12 | 13 | 14 | softwaiter 15 | 一个仿Hutool的.Net工具类库 16 | .Net常用方法工具类库(正则表达式常用判断、日期时间常用方法、XML快速遍历、动态扩展对象、图片验证码生成、阿里/腾讯短信发送、发送邮件、Json配置文件解析、加密解密等等) 17 | https://github.com/softwaiter/Xmtool 18 | https://github.com/softwaiter/Xmtool 19 | git 20 | README.md 21 | JSON;Regex;XML;Crypto;Hash;Http;DateTime;SendMail;SendSms;Captcha;like-hutool 22 | MIT 23 | xmtool.png 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 | True 56 | \ 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | True 72 | \ 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Source/CryptoTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Security.Cryptography; 4 | using System.Text; 5 | 6 | namespace CodeM.Common.Tools 7 | { 8 | public class CryptoTool 9 | { 10 | private static CryptoTool sCTool = new CryptoTool(); 11 | 12 | private CryptoTool() 13 | { 14 | } 15 | 16 | internal static CryptoTool New() 17 | { 18 | return sCTool; 19 | } 20 | 21 | public string Base64Encode(string text, string encoding = "utf-8") 22 | { 23 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(text); 24 | return Convert.ToBase64String(bytes); 25 | } 26 | 27 | public string Base64Decode(string base64Text, string encoding = "utf-8") 28 | { 29 | byte[] bytes = Convert.FromBase64String(base64Text); 30 | return Encoding.GetEncoding(encoding).GetString(bytes); 31 | } 32 | 33 | private void GenerateAESKeyIV(string aesKey, out byte[] key, out byte[] iv, string encoding) 34 | { 35 | byte[] bytes = Encoding.GetEncoding(encoding).GetBytes(aesKey); 36 | 37 | using (SHA256 sha256 = SHA256.Create()) { 38 | sha256.ComputeHash(bytes); 39 | key = sha256.Hash; 40 | sha256.Clear(); 41 | } 42 | 43 | using (MD5 md5 = MD5.Create()) { 44 | md5.ComputeHash(bytes); 45 | iv = md5.Hash; 46 | md5.Clear(); 47 | } 48 | } 49 | 50 | public string AESEncode(string text, string key, string encoding = "utf-8") 51 | { 52 | byte[] source = Encoding.GetEncoding(encoding).GetBytes(text); 53 | 54 | byte[] _key; 55 | byte[] _iv; 56 | GenerateAESKeyIV(key, out _key, out _iv, encoding); 57 | 58 | byte[] target; 59 | 60 | using (Aes aes = Aes.Create()) 61 | { 62 | aes.Key = _key; 63 | aes.IV = _iv; 64 | 65 | using (MemoryStream ms = new MemoryStream()) 66 | { 67 | using (CryptoStream cs = new CryptoStream(ms, 68 | aes.CreateEncryptor(), CryptoStreamMode.Write)) 69 | { 70 | cs.Write(source, 0, source.Length); 71 | cs.FlushFinalBlock(); 72 | target = (byte[])ms.ToArray(); 73 | } 74 | } 75 | } 76 | 77 | return Convert.ToBase64String(target); 78 | } 79 | 80 | public string AESDecode(string aesText, string key, string encoding = "utf-8") 81 | { 82 | byte[] source = Convert.FromBase64String(aesText); 83 | 84 | byte[] _key; 85 | byte[] _iv; 86 | GenerateAESKeyIV(key, out _key, out _iv, encoding); 87 | 88 | byte[] target; 89 | using (Aes aes = Aes.Create()) 90 | { 91 | aes.Key = _key; 92 | aes.IV = _iv; 93 | 94 | using (MemoryStream ms = new MemoryStream()) 95 | { 96 | using (CryptoStream cs = new CryptoStream(ms, 97 | aes.CreateDecryptor(), CryptoStreamMode.Write)) 98 | { 99 | cs.Write(source, 0, source.Length); 100 | cs.FlushFinalBlock(); 101 | target = (byte[])ms.ToArray(); 102 | } 103 | } 104 | } 105 | 106 | return Encoding.GetEncoding(encoding).GetString(target); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /Test/DateTimeTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using System; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Test 7 | { 8 | public class DateTimeTest 9 | { 10 | private ITestOutputHelper output; 11 | 12 | public DateTimeTest(ITestOutputHelper output) 13 | { 14 | this.output = output; 15 | } 16 | 17 | [Fact] 18 | public void Test() 19 | { 20 | DateTime dtNow = DateTime.Now; 21 | long ts = Xmtool.DateTime().GetUtcTimestamp10(); 22 | Assert.True((ts + "").Length == 10); 23 | 24 | DateTime dt = Xmtool.DateTime().GetLocalDateTimeFromUtcTimestamp10(ts); 25 | Assert.Equal(dt.Year, dtNow.Year); 26 | Assert.Equal(dt.Month, dtNow.Month); 27 | Assert.Equal(dt.Day, dtNow.Day); 28 | Assert.Equal(dt.Hour, dtNow.Hour); 29 | Assert.Equal(dt.Minute, dtNow.Minute); 30 | Assert.Equal(dt.Second, dtNow.Second); 31 | } 32 | 33 | [Fact] 34 | public void Test2() 35 | { 36 | DateTime dtNow = DateTime.Now; 37 | long ts = Xmtool.DateTime().GetUtcTimestamp13(); 38 | Assert.True((ts + "").Length == 13); 39 | 40 | DateTime dt = Xmtool.DateTime().GetLocalDateTimeFromUtcTimestamp13(ts); 41 | Assert.Equal(dt.Year, dtNow.Year); 42 | Assert.Equal(dt.Month, dtNow.Month); 43 | Assert.Equal(dt.Day, dtNow.Day); 44 | Assert.Equal(dt.Hour, dtNow.Hour); 45 | Assert.Equal(dt.Minute, dtNow.Minute); 46 | Assert.Equal(dt.Second, dtNow.Second); 47 | } 48 | 49 | [Fact] 50 | public void Test3() 51 | { 52 | string timespan = "1000ms"; 53 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(timespan); 54 | Assert.NotNull(ts); 55 | Assert.True(ts.Value.TotalSeconds == 1); 56 | } 57 | 58 | [Fact] 59 | public void Test4() 60 | { 61 | string timespan = "1m"; 62 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(timespan); 63 | Assert.NotNull(ts); 64 | Assert.True(ts.Value.TotalSeconds == 60); 65 | } 66 | 67 | [Fact] 68 | public void Test5() 69 | { 70 | string timespan = "1h"; 71 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(timespan); 72 | Assert.NotNull(ts); 73 | Assert.True(ts.Value.TotalSeconds == 60 * 60); 74 | } 75 | 76 | [Fact] 77 | public void Test6() 78 | { 79 | string timespan = "15"; 80 | TimeSpan? ts = Xmtool.DateTime().GetTimeSpanFromString(timespan); 81 | Assert.NotNull(ts); 82 | Assert.True(ts.Value.TotalSeconds == 15); 83 | } 84 | 85 | [Fact] 86 | public void Test7() 87 | { 88 | bool bRet = Xmtool.DateTime().CheckStringTimeSpan("1s"); 89 | Assert.True(bRet); 90 | } 91 | 92 | [Fact] 93 | public void Test8() 94 | { 95 | try 96 | { 97 | bool bRet = Xmtool.DateTime().CheckStringTimeSpan("abc"); 98 | } 99 | catch (Exception exp) 100 | { 101 | Assert.Contains("错误的时间段格式", exp.Message); 102 | } 103 | } 104 | 105 | [Fact] 106 | public void Test9() 107 | { 108 | bool bRet = Xmtool.DateTime().CheckStringTimeSpan("abc", false); 109 | Assert.False(bRet); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Test/WebTest.cs: -------------------------------------------------------------------------------- 1 | using CodeM.Common.Tools; 2 | using CodeM.Common.Tools.DynamicObject; 3 | using CodeM.Common.Tools.Web; 4 | using System; 5 | using System.Net; 6 | using Xunit; 7 | using Xunit.Abstractions; 8 | 9 | namespace Test 10 | { 11 | public class WebTest 12 | { 13 | private ITestOutputHelper output; 14 | 15 | public WebTest(ITestOutputHelper output) 16 | { 17 | this.output = output; 18 | } 19 | 20 | [Fact] 21 | public async void GetTest() 22 | { 23 | HttpResponseExt rep = await Xmtool.Web.Client().GetAsync("http://www.baidu.com"); 24 | Assert.Equal(HttpStatusCode.OK, rep.StatusCode); 25 | try 26 | { 27 | dynamic jsonObj = rep.Json; 28 | } 29 | catch (Exception exp) 30 | { 31 | Assert.Contains("JSON", exp.Message); 32 | } 33 | } 34 | 35 | [Fact] 36 | public async void PostTest() 37 | { 38 | dynamic data = new DynamicObjectExt(); 39 | data.channel = 0; 40 | data.d = 10; 41 | data.domains = "163.com"; 42 | data.l = 0; 43 | data.pd = "mail126"; 44 | data.pkid = "QdQXWEQ"; 45 | data.pw = "SHywNfsbpCUH6U/26KQRLYBOa7eMRZp0MqyrF7sfng2hxnRRWoLRNNrPxFF87Wnfz5mbusIBXPLJkN/Ruc2ucA3dYcNQ0k+3DYRphkq6K7xVaJAV2Znw8A25Rl4V/zBmeRvHIvwf0Q4DQJnK+Fbj4+yo3P0bIge7euoPEGrbHUs="; 46 | data.pwdKeyUp = 0; 47 | data.rtid = "QQ1MeSNpLaDGwtZG50SlKRzhgz7yAU75"; 48 | data.t = 1624606697553; 49 | data.tk = "2d47c20c858e673ab49bf00fe7541807"; 50 | data.topURL = "https://www.126.com/"; 51 | data.un = "softwaiter@126.com"; 52 | 53 | HttpResponseExt rep = await Xmtool.Web.Client() 54 | .SetJsonContent(data) 55 | .PostAsync("https://passport.126.com/dl/zj/mail/gt"); 56 | Assert.Equal(HttpStatusCode.OK, rep.StatusCode); 57 | Assert.Equal("401", rep.Json.ret); 58 | } 59 | 60 | [Fact] 61 | public void DoubleRequestTest() 62 | { 63 | HttpResponseExt rep = Xmtool.Web.Client().Get("https://api.juejin.cn/interact_api/v1/pin_tab_lead"); 64 | Assert.Equal(HttpStatusCode.OK, rep.StatusCode); 65 | rep = Xmtool.Web.Client().Get("http://www.baidu.com"); 66 | Assert.Equal(HttpStatusCode.OK, rep.StatusCode); 67 | Assert.Contains("", rep.Content); 68 | } 69 | 70 | [Fact] 71 | public void ScriptTagTest() 72 | { 73 | string str = "
hello world.
"; 74 | string str2 = Xmtool.Web.Security().Xss(str); 75 | Assert.DoesNotContain("script", str2); 76 | } 77 | 78 | [Fact] 79 | public void OnClickTest() 80 | { 81 | string str = "
hello world.
"; 82 | string str2 = Xmtool.Web.Security().Xss(str); 83 | Assert.DoesNotContain("alert", str2); 84 | } 85 | 86 | [Fact] 87 | public void ImageSrcTest() 88 | { 89 | string str = "
hello world.
"; 90 | string str2 = Xmtool.Web.Security().Xss(str); 91 | Assert.DoesNotContain("alert", str2); 92 | } 93 | 94 | [Fact] 95 | public void IframeSrcTest() 96 | { 97 | string str = "
hello world.