后端开发 文章

DotNet平台中 IL / CTS / CLS / CLR 都是什么?
后端开发
2021-03-12 0k

DotNet平台中 IL / CTS / CLS / CLR 都是什么?

IL(MSIL): 可以执行的二进制代码(托管代码) CTS: .Net平台通用数据类型(Common Type System) CLS: .Net平台通用语言规范(语法)(Common Language Specification ) CLR: 公共语言运行时( Common Language Runtime ) JIT: 即时编译器(Just in time) 关系 各个语言(VB.Net、F#)使用自己的JIT按照CTS、CLS编译成可以在CLR上运行的IL

dotnet .NET CLR
阅读更多
NPOI 根据模板导出 word文档
后端开发
2020-11-21 0k

NPOI 根据模板导出 word文档

文档模板: 单一字段替换:#batchNo# 需要循环的表格:$mx.NTime$ 生成后文档: 调用方式: NpoiHeplper.Export("OffShelfInfoTemplate.doc", $"new{dt}.doc", data); data数据为字典格式 var dt = DateTime.Now.ToString("yyyyMMddHHmmss"); Dictionary<string, object> data = new Dictionary<string, object>(); List<Dictionary<string, object>> list = new List<Dictionary<string, object>>(); Dictionary<string, object> item1 = new Dictionary<string, object>(); item1.Add("NTime", "2020-11-21"); item1.Add("StoreName", "先南小吃"); item1.Add("Addres", "北京昌平区中街211"); item1.Add("Num", "5"); item1.Add("Name", "杨过"); list.Add(item1); // new item2 item3 item4... //list.Add(item2); //list.Add(item3); //list.Add(item4); //new xqList data.Add("batchNo", $"No.{DateTime.Now.ToString("ddHHmmss")}"); data.Add("noticeTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); data.Add("userName", "张三"); data.Add("ApprovalDate", DateTime.Now.ToString("yyyy-MM-dd")); data.Add("mx", list); //data.Add("xq", xqList); 主要代码: /// <summary> /// 输出模板word文档 /// </summary> /// <param name="tempFilePath">docx文件路径</param> /// <param name="outPath">输出文件路径</param> /// <param name="data">字典数据源</param> public static void Export(string tempFilePath, string outPath, Dictionary<string, object> data) { using (FileStream stream = File.

dotnet NPOI Word文档
阅读更多
DotNet Core 项目 添加Swagger 自动构建接口文档
后端开发
2020-06-08 0k

DotNet Core 项目 添加Swagger 自动构建接口文档

1、NuGet引用 Swashbuckle.AspNetCore 2、Startup类中ConfigureServices函数添加代码 #region Swagger public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); #region Swagger services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Version = "1.0", Title = "SwaggerDemo API", Description = "SwaggerDemo文档", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "SwaggerDemo", Email = "raikay@163.com", Url = "http://www.raikay.cn/" } }); }); #endregion } #endregion 3、启动Http中间件:编辑Configure类 public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } #region Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.

dotnet swagger .NET Core
阅读更多
什么是JWT? Json Web Token介绍
后端开发
2020-05-16 0k

什么是JWT? Json Web Token介绍

什么是jwt? JWT 英文名是 Json Web Token ,是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范,经常用在跨域身份验证。 JWT 以 JSON 对象的形式安全传递信息。因为存在数字签名,因此所传递的信息是安全的。 由三部分组成: Header(头部) Payload(数据) Signature(签名) JWT=头部编码+数据编码+加密(头部编码+数据编码+key) 编码采用base64编码,加密采用头部alg声明编码方式加密 一:头部(Header) JWT 头描述了 JWT 元数据,是一个 JSON 对象,它的格式如下: {"typ":"JWT","alg":"HS256"} 这里的 alg 属性表示签名所使用的算法,JWT 签名默认的算法为 HMAC SHA256 , alg 属性值 HS256 就是 HMAC SHA256 算法。typ 属性表示令牌类型,这里就是 JWT。 Base64编码后是下面这样: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 二:载荷(playload) 有效载荷是 JWT 的主体,同样也是个 JSON 对象。有效载荷包含三个部分: 1、标准注册声明: 标准注册声明不是强制使用是的,但是我建议使用。它一般包括以下内容: iss:jwt的签发者/发行人; sub:主题; aud:接收方; exp:jwt过期时间; nbf:jwt生效时间; iat:签发时间 jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 2、公共声明: 可以在公共声明添加任何信息,我们一般会在里面添加用户信息和业务信息,但是不建议添加敏感信息,因为公共声明部分可以在客户端解密。 3、私有声明: 私有声明是服务器和客户端共同定义的声明,同样这里不建议添加敏感信息。 下面这个代码段就是定义了一个有效载荷: {"sub":"1234567890","name":"John Doe","admin":true} Base64编码: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9 三:签名(signature) 这个部分主要是确保数据不会被篡改,需要base64加密后的header和base64加密后的payload使用.

JWT 单点登录 http
阅读更多
Dto / Model / Entity 区别
后端开发
2020-02-11 0k

Dto / Model / Entity 区别

Entity 数据表对应到实体类的映射 Model Model是MVC中一个概念,可能不和Entity一一对应,因为展示在View层中数据可能是一个Entity的精简,也可能是多个Entity的组合。 Model是一个高度优化组合或者精简后的一个用于在View层展示数据的对象。 DTO 数据传输对象(Data Transfer Object)。 用于系统间数据传输的对象,数据传输目标往往是数据访问对象从数据库中检索数据。 鸣谢: https://www.zhihu.com/question/25256772 http://www.liuhuachao.com/blog/2018/05/20/entity-model-dto/

dotnet DTO Model
阅读更多
分布式唯一ID - 雪花ID Snowflake .Net版
后端开发
2020-02-11 0k

分布式唯一ID - 雪花ID Snowflake .Net版

雪花Id介绍: 雪花ID是用一个64位的整形数字来做ID,对应.net中的long,数据库中的bigint,雪花算法的原始版本是scala版,用于生成分布式ID(纯数字,时间顺序),订单编号等。 生成的雪花Id: 35324861574164480 35324861578358784 35324861578358785 对比自增和Guid: 自增ID: 对于数据敏感场景不宜使用,且不适合于分布式场景。 GUID: 采用无意义字符串,且36位字符串太长,数据量增大时造成访问过慢,且不宜排序。 算法描述: 最高位是符号位,始终为0,不可用。 41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。 10位的机器标识,10位的长度最多支持部署1024个节点。 12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。 雪花算法改进,时钟回拨: 雪花ID严重依赖系统当前时间,当系统时间被人为反后调整时,算法会出问题,可能会出重复ID.Snowflake原算法是在检测到系统时间被回调后直接抛异常.本代码在时钟回拨后,会将生成的ID时间戳停留在最后一次时间戳上(每当序列溢出时会往前走一毫秒),等待系统时间追上后即可以避过时钟回拨问题. 这种处理方式的优点是时钟回拨后不会异常,能一直生成出雪花ID,但缺点是雪花ID中的时间戳不是系统的当前时间,会是回拨前的最后记录的一次时间戳,但相差也不大.不知道有没有什么生产系统会对这个时间戳要求非常严格,无法使用这种补救方式的? 当然停掉系统后的时钟回拨是无法处理的,这种还是会有可能出现重复ID的. 生成Id以及解析Id方法: 源码git地址:https://gitee.com/itsm/learning_example/tree/master/snowflake-雪花Id public class SnowflakeId { // 开始时间截((new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc)-Jan1st1970).TotalMilliseconds) private const long twepoch = 1577836800000L; // 机器id所占的位数 private const int workerIdBits = 5; // 数据标识id所占的位数 private const int datacenterIdBits = 5; // 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) private const long maxWorkerId = -1L ^ (-1L << workerIdBits); // 支持的最大数据标识id,结果是31 private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 序列在id中占的位数 private const int sequenceBits = 12; // 数据标识id向左移17位(12+5) private const int datacenterIdShift = sequenceBits + workerIdBits; // 机器ID向左移12位 private const int workerIdShift = sequenceBits; // 时间截向左移22位(5+5+12) private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) private const long sequenceMask = -1L ^ (-1L << sequenceBits); // 数据中心ID(0~31) public long datacenterId { get; private set; } // 工作机器ID(0~31) public long workerId { get; private set; } // 毫秒内序列(0~4095) public long sequence { get; private set; } // 上次生成ID的时间截 public long lastTimestamp { get; private set; } /// <summary> /// 雪花ID /// </summary> /// <param name="datacenterId">数据中心ID</param> /// <param name="workerId">工作机器ID</param> public SnowflakeId(long datacenterId,long workerId ) { if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new Exception(string.

分布式 Snowflake 雪花ID
阅读更多
Cookie、session、token、jwt简单说明
后端开发
2019-09-15 0k

Cookie、session、token、jwt简单说明

【Cookie】:是由服务器端生成,发送给客户端的文本文件,下次请求时自动发送给服务端。 【session】:在服务端保存用户的状态,并用一个cookie标识进行存取 【token】:服务端把用户信息和密钥通过加密算法生成一个字符串 【jwt】:一种基于 JSON 的开放标准,一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。 可以理解是一种特殊的token

http Cookie Session
阅读更多
正则表达式元字符简介
后端开发
2019-08-06 0k

正则表达式元字符简介

元字符1 .:匹配除\n之外的任何单个字符。 例如正则表达式“b.g”能匹配如下字符串:“big”、“bug”、“b g”,但是不匹配“buug”,“b..g”可以匹配“buug”。 [ ] :匹配括号中的任何一个字符(范围,字符集合)。 例如正则表达式“b[aui]g”匹配bug、big和bag,但是不匹配beg、baug。可以在括号中使用连字符“-”来指定字符的区间来简化表示,例如正则表达式[0-9]可以匹配任何数字字符,这样正则表达式“a[0-9]c”等价于“a[0123456789]c”就可以匹配“a0c”、“a1c”、“a2c”等字符串;还可以制定多个区间,例如“[A-Za-z]”可以匹配任何大小写字母,“[A-Za-z0-9]”可以匹配任何的大小写字母或者数字。思考:x[这里必须是元音]y,如何写正则?【当.出现在[]中,则表示普通.,不作为元字符。】 | :将两个匹配条件进行逻辑“或”运算。 例如‘z|food’ 能匹配 “z” 或 “food”。‘(z|f)ood’ 则匹配 “zood” 或 “food”。 //注意^$问题。 ():将 () 之间括起来的表达式定义为“组”(group) 将匹配这个表达式的字符保存到一个临时区域,这个元字符在字符串提取的时候非常有用。把一些字符表示为一个整体。改变优先级、定义提取组两个作用。 元字符2(限定符) 限定符:限定前面的正则表达式出现的次数。 *:匹配0至多个在它之前的子表达式,和通配符*没关系。等价于{0,}。 例如正则表达式“zo*”(等同于z(o)*)能匹配 “z” 、“zo”以及 “zoo”;因此“.*”意味着能够匹配任意字符串。“z(b|c)*“→zb、zbc、zcb、zccc、zbbbccc。“z(ab)*“能匹配z、zab、zabab(用括号改变优先级)。 +:匹配前面的子表达式一次或多次,等价于{1,} 例如正则表达式9+匹配9、99、999等。 “zo+”能匹配 “zo”以及 “zoo” ,不能匹配"z”。 **? :匹配前面的子表达式零次或一次。等价于:{0,1} ** 例如,“do(es)?” 可以匹配 “do” 或 “does” 。【colou?r、favou?r】一般用来匹配“可选部分”。(终止贪婪模式) {n} :匹配确定的 n 次。“zo{2}”→zoo。 例如,“e{2}” 不能匹配“bed”中的“e”,但是能匹配“seed”中的两个“e”。 //seeeed,不可以。 {n,} :至少匹配n次。 例如,“e{2,}”不能匹配“bed”中的“e”(只出现一次,至少两次),但能匹配 “seeeeeeeed”中的所有“e”。 {n,m} :最少匹配 n 次且最多匹配 m 次。 例如“e{1,3}”将匹配“seeeeeeeed”中的前三个“e”。 {2,5}//bed,seed,seeed;beeeeed错误。 元字符3 ^(shift+6) :匹配一行的开始。 例如正则表达式“^regex”能够匹配字符串“regex我会用”的开始,但是不能匹配“我会用regex”。^另外一种意思:非!([^0-9]) $ :匹配行结束符。

dotnet 正则 正则表达式
阅读更多
正则表达式在C#中的使用
后端开发
2019-08-06 0k

正则表达式在C#中的使用

正则表达式简介 正则表达式是对字符串的操作 正则表达式是一个用来描述字符串特征的表达式。 特征:必须出现的内容、可能出现的内容、不能出现的内容。 观察字符串规律,根据规律总结特征,然后根据特定字符串的特征来编写正则表达式。 常用函数: Regex.IsMatch(); //判断是否匹配 Regex.Match();//提取某个(一个)匹配 Regex.Matches();//提取所有的匹配 Regex.Replace();//替换 Regex.Split();//分割 Regex.IsMatch() 练习1:判断是否是合法的邮政编码(6位数字) lRegex.IsMatch("100830","^[0-9]{6}$") Regex.IsMatch("119", @"^\d{6}$"); 解释:由元字符定义得知“[0-9]”表示0到9的任意字符,“{6}”表示前面的字符匹配6次,因此“[0-9]{6}”中的{6}表示对数字匹配6次(000000123)。简写表达式得知“[0-9]”可以被“\d”代替,所以第二种写法“\d{6}”也是正确的。 练习2:判断一个字符串是不是身份证号码。 长度为15位或者18位的字符串,首位不能是0。 如果是15位,则全部是数字。 如果是18位,则前17位都是数字,末位可能是数字也可能是X。 写法一:^[1-9][0-9]{14}([0-9]{2}[0-9Xx])?$ 写法二: ^([1-9][0-9]{14}|[1-9][0-9]{16}[0-9X])$ 练习3:判断字符串是否为正确的国内电话号码,不考虑分机。 •010-8888888或010-88888880或010xxxxxxx •0335-8888888或0335-88888888(区号-电话号)03358888888 •10086、10010、95595、95599、95588(5位) •13888888888(11位都是数字) Regex.IsMatch(phoneNumber, @“^((\d{3,4}\-?\d{7,8})|(\d{5})|(\d{11}))$”); //或者 Regex.IsMatch(phoneNumber, @“^((\d{3,4}\-?\d{7,8})|(\d{5}))$”); 按照要求一个一个写,都用|连起来。注意:由于区号有时为010-xxxxxxx有时为010xxxxxxx,-可有可无,所以需要?,由于-表示一个区间,所以这里要转义-。最后不要忘记在所有|的最外层加一对() Regex.Match() / Matches() string msg = "大家好呀,hello,2010年10月10日是个好日子。恩,9494.吼吼!886."; Match match1 = Regex.Match(msg, @"\d", RegexOptions.ECMAScript); //提取得到 2 (逐个提取) Match match2 = Regex.Match(msg, @"\d+", RegexOptions.ECMAScript); //提取得到2010 //提取所有的匹配的字符串 MatchCollection matches = Regex.

dotnet 正则 C#
阅读更多
Net Core 3.x 禁用序列化时自动首字母小写
后端开发
2019-03-11 0k

Net Core 3.x 禁用序列化时自动首字母小写

public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddJsonOptions(config => { //去掉转小写功能 // System.Text.Json.JsonNamingPolicy.CamelCase:转小写 // null:不转小写 config.JsonSerializerOptions.PropertyNamingPolicy =null; }); }

dotnet .NET Core 序列化
阅读更多