解决方案 今天像往常一样,编写文章,并使用gulp bulid压缩代码,但是一运行:gulp build 就出现了这个错误:AssertionError: Task function must be specified。 gulp项目需要全局安装gulp和项目内安装gulp,通过 gulp -v 查看全局gulp 和本地项目的gulp版本: image.png 这俩显然,不一致。 下面,我们可以看到项目里记录的gulp的版本号: image.png 可以卸载修改json文件里面的版本号:为gulp 3 版本。如 3.9.1 重新运行 npm install gulp 3 和 gulp 4运行方式是不一样的,所以会出现错误。具体细节,可以看这里 gup3 VS gulp4 区别 Gulp 4最大的变化就是你不能像以前那样传递一个依赖任务列表。 Gulp3,如果有一个任务A,B和C的列表,你想在一个序列中运行(确保A在B开始之前完成,而B在C开始之前完成),代码如下:
|
1 2 3 4 5 6 7 8 9 |
gulp.task('a', function () { // Do something. }); gulp.task('b', ['a'], function () { // Do some stuff. }); gulp.task('c', ['b'], function () { // Do some more stuff. }); |
在Gulp 4中,你不能再这样做了。你会得到以下错误:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
assert.js:85 throw new assert.AssertionError({ ^ AssertionError: Task function must be specified at Gulp.set [as _setTask] (/home/hope/web/node_modules/undertaker/lib/set-task.js:10:3) at Gulp.task (/home/hope/web/node_modules/undertaker/lib/task.js:13:8) at Object.<anonymous> (/home/hope/web/gulpfile.js:31:6) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.require (module.js:497:17) at require (internal/module.js:20:19) |
不要用Gulp3的方式指定依赖任务,你需要使用gulp.series和gulp.parallel,因为gulp任务现在只有两个参数。 gulp.series:按照顺序执行 gulp.paralle:可以并行计算
|
1 2 3 |
gulp.task('my-tasks', gulp.series('a', 'b', 'c', function() { // Do something after a, b, and c are finished. })); |
|
1 2 3 |
gulp.task('build', gulp.parallel('styles', 'scripts', 'images', function () { // Build the website. })); |
或者这样
|
1 2 3 |
gulp.task('my-tasks', gulp.series('a', gulp.parallel('styles','scripts', 'images'), 'b', 'c', function() { // Do something after a, b, and c are finished. })); |
相关任务必须在被调用之前发生。 参考: https://github.com/gulpjs/gulp/blob/master/docs/API.md https://www.fastless.com/gulp-4 https://www.jianshu.com/p/40b99bed3127 作者:cuteximi_1995 链接:https://www.jianshu.com/p/c30ff8592421 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
View Detailsvs code格式化代码的快捷键如下:(来源于这里) On Windows Shift + Alt + F On Mac Shift + Option + F On Ubuntu Ctrl + Shift + I 但是自带的格式化并不能满足我的需求,这个时候,不得不说插件大法好。 1、代码格式化为eslint风格(参考自这里) 需要插件:eslint 在设置中添加: "eslint.autoFixOnSave": true, "eslint.validate": [ "javascript", "javascriptreact", { "language": "html", "autoFix": true }, { "language": "vue", "autoFix": true } ], eslint.autoFixOnSave 用来进行保存时自动格式化,但是默认只支持 javascript .js 文件。 eslint.validate 用来配置作用的文件类型。 然后在保存代码的时候,就会自动格式化为eslint风格(需要保存多次)。 2、HTML格式化代码缩进 需要插件:Vetur Vetur是一个功能非常强大的插件,为 vs code 编写Vue代码提供了强大的支持,也支持大多数主流的前端开发脚本。具体可以看这里->Vetur文档 安装这个插件后,可以在设置中看到如下的内容: 为了让HTML代码可以格式化缩进,添加如下一条:
|
1 |
<span class="hljs-string">"vetur.format.defaultFormatter.html"</span>: <span class="hljs-string">"prettier"</span> |
然后用格式化代码的快捷键就可以了。 from:https://blog.csdn.net/latency_cheng/article/details/80409202
View Detailsgulpfile.js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
var gulp = require('gulp'); var webserver = require('gulp-webserver'); gulp.task('webserver', function () { gulp.src('./') .pipe(webserver({ host: 'localhost', port: 3000, livereload: true, open: './pages/myPages/login.html', directoryListing: { enable: true, path: './' }, proxies: [ { source: '/api', target: 'http://jsonplaceholder.typicode.com' } ] })) }); gulp.task('default', ['webserver'], function () { console.log('成功'); }); |
1、在本地起一个服务,端口号为3000。 2、open:默认打开的文件的路径 3、directoryListing:是否显示文件列表 4、proxies: 设置代理 接口调用: 接口调用 url http://localhost:3000/api 作者:动次动次forever 链接:https://www.jianshu.com/p/237bc5c04fa1 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
View Details为什么需要使用代理? 目前,前端发展飞速,前后端分离式开发已经不是新鲜事儿。 1 如果前端只是静态的页面(不需要调用后端的api加载动态数据),那么前端直接在本地开发即可。 即使是前后端分开部署,只需要单独为前端启动一个服务,使用gulp-connect即可。不会?(请戳gulp之用gulp-connect开启一个本地webServer) 2 如果前端需要调用后端提供的接口呢?除非前后端部署在同一个服务器上,否则由于浏览器的限制是没办法跨域请求数据的。真实情况是,我们在本地开发时就需要访问接口,这时后端的程序猿给你的往往是这样一个地址 http://192.168.1.123/controller/action,有人说上传代码到http://192.168.1.123/放在一个目录下不就行了,是啊!可以的。但是好麻烦有没有,调试接口需要传代码上去!!!! 3 如果我的数据是从其他的服务器来的呢?例如我想访问豆瓣的开放接口
|
1 2 3 4 |
$.post(<span class="hljs-string">'https://api.douban.com/v2/book/1220562'</span>,{},<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{ <span class="hljs-built_in">console</span>.log(data); }) |
豆瓣告诉你,不行!你跨域了! 所以,还是代理来的方便。 代理是个什么鬼? 代理请求通俗点讲,就是把发往 a.com的请求,通过代理服务器发送到b.com。 怎么开启一个代理? 代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<span class="hljs-comment">//服务端口</span> <span class="hljs-keyword">const</span> PORT=<span class="hljs-number">8000</span>; <span class="hljs-comment">//启动服务的根目录</span> <span class="hljs-keyword">const</span> server_root=<span class="hljs-string">'src'</span> <span class="hljs-comment">//引用gulp</span> <span class="hljs-keyword">var</span> gulp = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp'</span>); <span class="hljs-comment">//引用gulp开启服务的插件</span> <span class="hljs-keyword">var</span> connect = <span class="hljs-built_in">require</span>(<span class="hljs-string">'gulp-connect'</span>); <span class="hljs-comment">//引用插件 gulp代理中间件插件</span> <span class="hljs-keyword">var</span> proxy = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http-proxy-middleware'</span>); <span class="hljs-comment">//开启服务</span> gulp.task(<span class="hljs-string">'proxyServer'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{ connect.server({ <span class="hljs-attr">root</span>: [server_root], <span class="hljs-attr">port</span>: PORT, <span class="hljs-attr">middleware</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">connect, opt</span>) </span>{ <span class="hljs-keyword">return</span> [ proxy(<span class="hljs-string">'/api'</span>, { <span class="hljs-attr">target</span>: <span class="hljs-string">'https://api.douban.com/v2'</span>,<span class="hljs-comment">//代理的目标地址</span> changeOrigin:<span class="hljs-literal">true</span>,<span class="hljs-comment">//</span> pathRewrite:{<span class="hljs-comment">//路径重写规则 </span> <span class="hljs-string">'^/api'</span>:<span class="hljs-string">''</span> } }) ] } }); }); |
说明 '/api' =>匹配你要代理的请求地址前缀 target=》你要把请求代理到哪 pathRewrite =》是把你再页面中写的请求地址 某部分 重写为后面的字符串 (例子中讲 请求中写的 /api 重写为 空字符串) 也就是发往 /api/book/1220562的请求最终会被发往 https://api.douban.com/v2/book/1220562 页面写请求时的写法
|
1 2 3 4 |
$.post(<span class="hljs-string">'/api/book/1220562'</span>,{},<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{ <span class="hljs-built_in">console</span>.log(data); }) |
目录结构 image.png 运行效果 image.png 结语 当然还有其他的方式,比如 node、cros、jsonp、phpheader、nginx设置代理 作者:coder_turbo 链接:https://www.jianshu.com/p/cc543fd0d7c5 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
View Details由于我们的接口是通过springboot一键式打包成jar包发布到服务器的,因此在通过接口上传文件之后,客户端如果还需要再访问该文件,那就需要用到静态资源访问,spring配置如下:
|
1 2 3 |
spring: resources: static-locations: file:E:\workspace\serverWorkspace\upload\images\photo\20180820,file:/opt/www |
一个是widows下做测试使用,另一个是linux下测试服务器使用。 有时候你会发现可能配置了static-locations但无效,原因可能就是你的目录不对,请仔细检查一下,别问我怎么知道的 如此之后验证即可,如我的: 浏览器输入: localhost:9999/filename ——————— 作者:weixin_34387284 来源:CSDN 原文:https://blog.csdn.net/weixin_34387284/article/details/87066649 版权声明:本文为博主原创文章,转载请附上博文链接!
View Details|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<insert id="saveOrUpdate" > <selectKey keyProperty="count" resultType="int" order="BEFORE"> select count(*) from country where id = #{id} </selectKey> <if test="count > 0"> update country set countryname = #{countryname},countrycode = #{countrycode} where id = #{id} </if> <if test="count==0"> insert into country values(#{id},#{countryname},#{countrycode}) </if> </insert> |
注意如果insert的parameterType是自定义对象的话,对象里需要有count属性,否则会报count属性找不到的错误 from:https://ydlmlh.iteye.com/blog/2236671
View Details在这篇文章里面主要讲解如何在mybatis里面使用一对一、一对多、多表联合查询(类似视图)操作的例子。 注:阅读本文前请先大概看一下之前两篇文章。 一、表结构 班级表class,学生表student,班级学生关系表ClassStudent。 这里一个学生只会在一个班级里面,也就是一对一的关系;一个班级有多个学生,也就是一对多的关系。 结构如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
CREATE TABLE [dbo].[Class]( [class_id] [int] NOT NULL, [class_name] [varchar](50) NOT NULL, CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED ( [class_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] CREATE TABLE [dbo].[ClassStudent]( [class_id] [int] NOT NULL, [student_id] [int] NOT NULL ) ON [PRIMARY] CREATE TABLE [dbo].[Student]( [s_id] [int] NOT NULL, [s_name] [varchar](50) NOT NULL, CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED ( [s_id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] |
3张表的数据如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
insert into Class values(1,'三(1)班') insert into Class values(2,'三(2)班') insert into Class values(3,'三(3)班') insert into Class values(4,'三(4)班') insert into Student values(1001,'张三') insert into Student values(1002,'李四') insert into Student values(1003,'赵五') insert into Student values(1004,'王二麻子') insert into ClassStudent values(1,1001) insert into ClassStudent values(1,1003) insert into ClassStudent values(4,1002) insert into ClassStudent values(3,1004) |
二、在原项目下新建一个包com.mybatis.sqljoinrelation,在包里面新建一个sqlMapper.xml的映射文件,在项目的mybatis的配置文件conf.xml中对这个sqlMapper.xml进行注册,注册片段如下:
|
1 2 3 4 |
<!-- 注册映射文件 --> <mappers> <mapper resource="com/mybatis/sqljoinrelation/sqlMapper.xml" /> </mappers> |
紧接着在原项目下再新建一个包com.mybatis.bean,在里面新建实体类 学生:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.mybatis.bean; /** * 学生(临时) */ public class StudentTemp { private int studentid; private String studentname; private Class tempClass; public Class getTempClass() { return tempClass; } public void setTempClass(Class tempClass) { this.tempClass = tempClass; } public int getStudentid() { return studentid; } public void setStudentid(int studentid) { this.studentid = studentid; } public String getStudentname() { return studentname; } public void setStudentname(String studentname) { this.studentname = studentname; } @Override public String toString() { return "StudentTemp [studentid=" + studentid + ", studentname=" + studentname + ", tempClass=" + tempClass + "]"; } } |
班级:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.mybatis.bean; /** * 班级 */ public class Class { private int classid; private String classname; public int getClassid() { return classid; } public void setClassid(int classid) { this.classid = classid; } public String getClassname() { return classname; } public void setClassname(String classname) { this.classname = classname; } @Override public String toString() { return "Class [classid=" + classid + ", classname=" + classname + "]"; } } |
学生班级视图类:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.mybatis.bean; public class studentclass { private int s_id; private String s_name; private int class_id; private String class_name; public int getS_id() { return s_id; } public void setS_id(int s_id) { this.s_id = s_id; } public String getS_name() { return s_name; } public void setS_name(String s_name) { this.s_name = s_name; } public int getClass_id() { return class_id; } public void setClass_id(int class_id) { this.class_id = class_id; } public String getClass_name() { return class_name; } public void setClass_name(String class_name) { this.class_name = class_name; } @Override public String toString() { return "studentclass [s_id=" + s_id + ", s_name=" + s_name + ", class_id=" + class_id + ", class_name=" + class_name + "]"; } } |
三、查询操作 1、 一对一,查询学生编号等于1001且他所在班级信息 2、一对多,查询班级编号等于1且包含所有学生信息 3、类似视图查询学生编号等于1001且他所在班级信息 sqlMapper.xml如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mybatis.sqljoinrelation.sqlMapper"> <!-- 1、 获取某学生以及该学生所在班级的信息 --> <!-- 可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明, 如果用"*"代替,则mybatis会自动匹配resultMap中提供的列名 --> <select id="getStudentAndClass" parameterType="int" resultMap="studentClassMap"> select c.class_id,c.class_name,s.s_id,s.s_name from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where s.s_id = #{id} </select> <!-- resultMap中的type表示返回什么类型的对象 --> <resultMap type="com.mybatis.bean.StudentTemp" id="studentClassMap"> <!-- property 表示com.mybatis.bean.StudentTemp中的属性; column 表示表中的列名 --> <id property="studentid" column="s_id" /> <result property="studentname" column="s_name" /> <!-- association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称; javaType表示该属性是什么类型对象 --> <association property="tempClass" javaType="com.mybatis.bean.Class"> <!-- property 表示com.mybatis.bean.Class中的属性; column 表示表中的列名 --> <id property="classid" column="class_id" /> <result property="classname" column="class_name" /> </association> </resultMap> <!-- 2、获取某学生以及该学生所在班级的信息,类似视图实现方式 --> <!-- resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样; resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射 --> <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass"> select c.class_id,c.class_name,s.s_id,s.s_name from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where s.s_id = #{id} </select> <!-- 3、获取某班级以及班级里面所有学生的信息 --> <select id="getClassStudents" parameterType="int" resultMap="classStudentsMap"> select * from Class c left join ClassStudent cs on c.class_id = cs.class_id left join Student s on cs.student_id = s.s_id where c.class_id = #{id} </select> <resultMap type="com.mybatis.bean.ClassTemp" id="classStudentsMap"> <id property="classid" column="class_id"/> <result property="classname" column="class_name"/> <!-- property表示集合类型属性名称,ofType表示集合中的对象是什么类型 --> <collection property="students" ofType="com.mybatis.bean.Student"> <id property="studentid" column="s_id"/> <result property="studentname" column="s_name"/> </collection> </resultMap> </mapper> |
测试代码如下: 一对一与类似视图查询的代码在一起,如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.mybatis.sqljoinrelation; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /** * 一对一 */ public class testonetoone { public static void main(String[] args) { SqlSessionFactory factory = MybatisUtils.getFactory(); SqlSession session = null; try { session = factory.openSession(true); //1、StudentTemp String statement1 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClass"; System.out.println(session.selectOne(statement1, 1001)); //2、用model类型接收数据 String statement2 = "com.mybatis.sqljoinrelation.sqlMapper.getStudentAndClassView"; System.out.println(session.selectOne(statement2, 1001)); } catch (Exception e) { e.printStackTrace(); }finally{ session.close(); } } } |
一对多测试代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.mybatis.sqljoinrelation; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import com.mybatis.util.MybatisUtils; /** * 一对多 */ public class testonetomany { public static void main(String[] args) { SqlSessionFactory factory = MybatisUtils.getFactory(); SqlSession session = null; try { session = factory.openSession(true); //1、StudentTemp String statement = "com.mybatis.sqljoinrelation.sqlMapper.getClassStudents"; System.out.println(session.selectOne(statement, 1)); } catch (Exception e) { e.printStackTrace(); }finally{ session.close(); } } } |
四、sqlMapper.xml需要说明的问题 1、一对一:<association property="tempClass" javaType="com.mybatis.bean.Class"> association字面意思关联,这里只专门做一对一关联; property表示是com.mybatis.bean.StudentTemp中的属性名称; javaType表示该属性是什么类型对象 2、类似视图查询: <select id="getStudentAndClassView" parameterType="int" resultType="com.mybatis.bean.studentclass"> resultType 对应简单类型,也就是实体中的属性名称与数据库表字段名称一模一样; resultMap 对应复杂类型,属性名称与字段名称不一样可以通过resultMap中property,column进行映射,其中一对一与一对多都是用resultMap来映射 3、一对多:<collection property="students" ofType="com.mybatis.bean.Student"> collection字面意思是集合,这里专门做一对多关联 ,property表示集合类型属性名称,ofType表示集合中的对象是什么类型 4、<select>select * from …</student>与<select>select 字段1,字段2,字段3… from …</student> 可以显示指出c.class_id,c.class_name,s.s_id,s.s_name列明,如果用"*"代替,则mybatis会自动匹配resultMap或者resultType中提供的列名, 如果某对象存在列映射的属性,但是在select 后面找不到这个列,则在返回结果中,该列多映射的值为null。 至此,对于一对一、一对多、视图查询都能很好的解决,主要还是要重点关注第四点说明。 from:https://www.cnblogs.com/wucj/p/5148813.html
View Details1. 报错信息
|
1 2 3 4 5 6 7 8 |
Description: The bean 'dataSource', defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] and overriding is disabled. Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true |
2. 原因
|
1 2 |
相同名字不成功 |
3. 解决办法
|
1 2 3 4 |
main: allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册 |
from:https://blog.csdn.net/weixin_42633131/article/details/84782516
View Details本文目录 1. 摘要 2. MD5加密封装 3. AES的加密、解密 4. DES加密/解密 5. 总结 1. 摘要 C#中常用的一些加密和解密方案,如:md5加密、RSA加密与解密和DES加密等,Asp.Net Core 2.0下该如何调整与使用我们以前常用的解加密算法类呢,下面是我整理的MD5加密、AES&DES对称加解密、Encrypt&Decrypt加解密完整实例。希望能给大家提供一些参考和帮助。 2. MD5加密封装 MD5常用加密FormsAuthentication.HashPasswordForStoringInConfigFile在Net Freamwork4.5以后就不在支持,下面整理了32位或16位下的几个方法,以及不同写法,最后一个由从老版本迁移过来,后续淘汰不用。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; namespace NC.Common { /// <summary> /// 此类获取md5加密值均为大写,如果要获取小写:MD5Comm.Get32MD5One(xx).ToLower();或完善此类。 /// </summary> public class MD5Comm { #region --Expired code-- ///// <summary> ///// MD5加密 ///// </summary> //public string Md5(string txt) //{ // //return FormsAuthentication.HashPasswordForStoringInConfigFile(txt, "MD5");//此方法nf4.5后不再支持 //} //public string Md5Pass(string pwd) //{ // return Md5(pwd + "Jiahao"); //} #endregion /// <summary> /// 此代码示例通过创建哈希字符串适用于任何 MD5 哈希函数 (在任何平台) 上创建 32 个字符的十六进制格式哈希字符串 /// 官网案例改编 /// </summary> /// <param name="source"></param> /// <returns></returns> public static string Get32MD5One(string source) { using (MD5 md5Hash = MD5.Create()) { byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source)); StringBuilder sBuilder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString("x2")); } string hash = sBuilder.ToString(); return hash.ToUpper(); } } /// <summary> /// 获取16位md5加密 /// </summary> /// <param name="source"></param> /// <returns></returns> public static string Get16MD5One(string source) { using (MD5 md5Hash = MD5.Create()) { byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(source)); //转换成字符串,并取9到25位 string sBuilder = BitConverter.ToString(data, 4, 8); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 sBuilder = sBuilder.Replace("-", ""); return sBuilder.ToString().ToUpper(); } } //// <summary> /// </summary> /// <param name="strSource">需要加密的明文</param> /// <returns>返回32位加密结果,该结果取32位加密结果的第9位到25位</returns> public static string Get32MD5Two(string source) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); //获取密文字节数组 byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source)); //转换成字符串,32位 string strResult = BitConverter.ToString(bytResult); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 strResult = strResult.Replace("-", ""); return strResult.ToUpper(); } //// <summary> /// </summary> /// <param name="strSource">需要加密的明文</param> /// <returns>返回16位加密结果,该结果取32位加密结果的第9位到25位</returns> public static string Get16MD5Two(string source) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); //获取密文字节数组 byte[] bytResult = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(source)); //转换成字符串,并取9到25位 string strResult = BitConverter.ToString(bytResult, 4, 8); //BitConverter转换出来的字符串会在每个字符中间产生一个分隔符,需要去除掉 strResult = strResult.Replace("-", ""); return strResult.ToUpper(); } /// <summary> /// 自定义MD5函数,32位,从老版本迁移过来,后续淘汰不用。与Get32MD5One重复 /// </summary> public static string Get32MD5Old(string str) { byte[] b = Encoding.UTF8.GetBytes(str); b = new MD5CryptoServiceProvider().ComputeHash(b); string ret = ""; for (int i = 0; i < b.Length; i++) ret += b[i].ToString("x").PadLeft(2, '0'); return ret.ToUpper(); } } } |
3. AES的加密、解密 上面我们介绍了MD5加密封装,接下来分享给大家供大家参考一下AES加密、解密,AES要注意的是32位密匙。AES 加密解密(高级加密标准,是下一代的加密算法标准,速度快,安全级别高,目前 AES 标准的一个实现是 Rijndael 算法)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
using System; using System.IO; using System.Text; using System.Security.Cryptography; namespace NC.Common { /// <summary> /// 加密 /// </summary> public class AES { //默认密钥向量 private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F }; public static string Encode(string encryptString, string encryptKey) { encryptKey = GetSubString(encryptKey,0, 32, ""); encryptKey = encryptKey.PadRight(32, ' '); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32)); rijndaelProvider.IV = Keys; ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor(); byte[] inputData = Encoding.UTF8.GetBytes(encryptString); byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Convert.ToBase64String(encryptedData); } public static string Decode(string decryptString, string decryptKey) { try { decryptKey = GetSubString(decryptKey,0, 32, ""); decryptKey = decryptKey.PadRight(32, ' '); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey); rijndaelProvider.IV = Keys; ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); byte[] inputData = Convert.FromBase64String(decryptString); byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Encoding.UTF8.GetString(decryptedData); } catch { return ""; } } public static string GetSubString(string p_SrcString, int p_StartIndex, int p_Length, string p_TailString) { string myResult = p_SrcString; Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString); foreach (char c in Encoding.UTF8.GetChars(bComments)) { //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3) if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3')) { //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+")) //当截取的起始位置超出字段串长度时 if (p_StartIndex >= p_SrcString.Length) return ""; else return p_SrcString.Substring(p_StartIndex, ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length); } } if (p_Length >= 0) { byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString); //当字符串长度大于起始位置 if (bsSrcString.Length > p_StartIndex) { int p_EndIndex = bsSrcString.Length; //当要截取的长度在字符串的有效长度范围内 if (bsSrcString.Length > (p_StartIndex + p_Length)) { p_EndIndex = p_Length + p_StartIndex; } else { //当不在有效范围内时,只取到字符串的结尾 p_Length = bsSrcString.Length - p_StartIndex; p_TailString = ""; } int nRealLength = p_Length; int[] anResultFlag = new int[p_Length]; byte[] bsResult = null; int nFlag = 0; for (int i = p_StartIndex; i < p_EndIndex; i++) { if (bsSrcString[i] > 127) { nFlag++; if (nFlag == 3) nFlag = 1; } else nFlag = 0; anResultFlag[i] = nFlag; } if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1)) nRealLength = p_Length + 1; bsResult = new byte[nRealLength]; Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength); myResult = Encoding.Default.GetString(bsResult); myResult = myResult + p_TailString; } } return myResult; } } } |
4. DES加密/解密 除了MD5加密、AES加密/解密之外还经常用到DES加密、解密,注意的是DES的密匙是8位的,这里有家婆MD5加密一起使用。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
using System; using System.Security.Cryptography; using System.Text; namespace NC.Common { /// <summary> /// DES加密/解密类。 /// </summary> public class DESEncrypt { #region --加密-- /// <summary> /// 加密 /// </summary> /// <param name="Text"></param> /// <returns></returns> public static string Encrypt(string Text) { return Encrypt(Text, "ncmvc"); } /// <summary> /// 加密数据 /// </summary> /// <param name="Text"></param> /// <param name="sKey"></param> /// <returns></returns> public static string Encrypt(string Text, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] inputByteArray; inputByteArray = Encoding.Default.GetBytes(Text); string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8); des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey); des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); foreach (byte b in ms.ToArray()) { ret.AppendFormat("{0:X2}", b); } return ret.ToString(); } catch { return "error"; } } #endregion #region --解密-- /// <summary> /// 解密 /// </summary> /// <param name="Text"></param> /// <returns></returns> public static string Decrypt(string Text) { return Decrypt(Text, "ncmvc"); } /// <summary> /// 解密数据 /// </summary> /// <param name="Text"></param> /// <param name="sKey"></param> /// <returns></returns> public static string Decrypt(string Text, string sKey) { try { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); int len; len = Text.Length / 2; byte[] inputByteArray = new byte[len]; int x, i; for (x = 0; x < len; x++) { i = Convert.ToInt32(Text.Substring(x * 2, 2), 16); inputByteArray[x] = (byte)i; } string md5SKey = MD5Comm.Get32MD5One(sKey).Substring(0, 8); des.Key = ASCIIEncoding.ASCII.GetBytes(md5SKey); des.IV = ASCIIEncoding.ASCII.GetBytes(md5SKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); return Encoding.Default.GetString(ms.ToArray()); } catch { return "error"; } } #endregion } } |
5. 总结 Asp.Net Core 2.0下加解密封装类分享给大家,供参考!文中有不合理之处望告知,欢迎批评指正。以前做项目常用的几种加密方式,在Net Core2.0下经过重新整理,好的延续,不合理方法弃用。相关案例使用方法欢迎大家继续关注《Asp.Net Core 2.0项目实战》系列。 from:https://www.cnblogs.com/oorz/p/8878491.html
View Details简介 在我们之前的Asp.net mvc 开发中,一提到配置文件,我们不由的想到 web.config 和 app.config,在 core 中,我们看到了很多的变化,新的配置系统显得更加轻量级,具有更好的扩展性,并且支持多样化的数据源。 博客园对于这个的讲解很多,比如:Artche ,但是,没有点基础看老A的博客还是有些吃力的,对于老A介绍的配置,我也是看的一头雾水,在后面的文章中,我会用像我们这些菜鸟容易接受的方式,重新解释一下。 今天,我们以 appsettings.json 为例,读取一些简单的系统配置。 appsettings.json 在 第二章 中,我们在讲到EF上线文时,在 Startup.cs 添加 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection"))); 已经使用到了 appsettings.json 我们添加一些简单的系统配置,来演示一下读取 appsettings.json: { "ApplicationInsights": { "InstrumentationKey": "" }, "ConnectionStrings": { "SqlServerConnection": "Server=.;Database=db_wkmvc;User ID=sa_wkmvc;Password=123456;" }, "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "ApplicationConfiguration": { //文件上传路径 "FileUpPath": "/upload/", //是否启用单用户登录 "IsSingleLogin": "True", //允许上传的文件格式 "AttachExtension": "gif,jpg,jpeg,png,bmp,rar,zip,doc,docx,xls,xlsx,ppt,pptx,txt,flv,apk,mp4,mpg,ts,mpeg,mp3,bak,pdf", //图片上传最大值KB "AttachImagesize": 12400 } } 我们添加一个配置类 ApplicationConfiguration
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
1 public class ApplicationConfiguration 2 { 3 #region 属性成员 4 5 /// <summary> 6 /// 文件上传路径 7 /// </summary> 8 public string FileUpPath { get; set; } 9 /// <summary> 10 /// 是否启用单用户登录 11 /// </summary> 12 public bool IsSingleLogin { get; set; } 13 /// <summary> 14 /// 允许上传的文件格式 15 /// </summary> 16 public string AttachExtension { get; set; } 17 /// <summary> 18 /// 图片上传最大值KB 19 /// </summary> 20 public int AttachImagesize { get; set; } 21 #endregion 22 } |
在 Startup.cs 的 ConfigureServices 添加 services.Configure<ApplicationConfiguration>(Configuration.GetSection("ApplicationConfiguration")); 在Startup.cs的中添加 services.AddTransient<EWS.UI.APP.AppConfigurtaionServices>(); 添加一个领域层 AppConfigurtaionServices public class AppConfigurtaionServices { private readonly IOptions<ApplicationConfiguration> _appConfiguration; public AppConfigurtaionServices(IOptions<ApplicationConfiguration> appConfiguration) { _appConfiguration = appConfiguration; } […]
View Details