net core Webapi基础工程搭建(五)——缓存机制
前言
作为WebApi接口工程,性能效率是必不可少的,每次的访问请求,数据库读取,业务逻辑处理都或多或少耗费时间,偶尔再来个各种花式for循环,那就嗨翻天了,一些公有的数据,访问频繁且大致重复的数据,我们可以考虑通过缓存来放置内存存储,以内存空间换取时间上的提升,至于缓存的方法,Cache,Session,Cookie等,为什么用等呢,因为还有很多缓存的方法,如Redis,具体后面用到了会专门介绍。
Cache
net core中没有Cache,但是它有MemoryCache,其实,大差不差,毕竟都是Cache。
Cache在项目工程中使用的范围还是挺广泛的:
- 在个人开发的时候,我一般会把系统字典做缓存,方便调用提高响应速度
- 消息推送后,会把消息实体缓存
- 其他,自己看着办吧
首先,引入Microsoft.Extensions.Caching.Memory

这里我直接在Util引入,前面已经讲了,一个工程引入第三方,其他工程引入项目工程即可使用对应第三方类库。
引入完成后,我们就开始来使用这个MemoryCache吧。
//实例化
private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value,
new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding)
.SetAbsoluteExpiration(expiressAbsoulte));
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value,
isSliding
? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn)
: new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn));
return Exists(key);
}
这个地方大致列下如何使用,其实对于第三方的包,我们封装是为了减少其他开发人员的学习成本,后面的SqlSugar等类库一样,其实本身第三方已经做了一次封装整合,而我们是因为实际开发需要来针对不同的业务功能做不同的封装整合,接口开放等。
补个测试效果,写到Session才想起来,唉,果然写东西不能让打断,-,-||。


注意观察时间,一段时间后Cache过期销毁。

Session
最初鼓捣net core的时候,我确实没有过多关注Session这个会话模式,毕竟只有浏览器才能使用,之前跟别人谈到Session多爽的时候,说道Session其实本质上类似Cookie(当然我也不清楚),因为用户访问后会有个SessionID,有状态的访问会留下Cookie也是情有可原的,如果用户自己整个隐私模式访问,那,再见(你就在登录界面循环往复吧)。
在用户登录后,Session存储用户基本登录信息这个是web端常用的手段,毕竟跟浏览器打交道Cookie少不了,对于无状态访问授权的JWT也是折腾过,不过还是理解不透彻,统一的授发token的方式还是挺可取的,如果是多服务,多应用,负载均衡的场景,单点登录确实方便,但是我常规会自己生成token来通过Session或者Redis存储,实际效果应该是差不多吧。
好了,废话不多说,一样是引入Microsoft.AspNetCore.Session

引入完成后,在Startup.cs注册Session服务。
public void ConfigureServices(IServiceCollection services)
{
//…之前的代码
#region Session
services.AddSession(options =>
{
options.Cookie.Name = "April.Session";
options.IdleTimeout = TimeSpan.FromSeconds(2000);//设置session的过期时间
options.Cookie.HttpOnly = true;//设置在浏览器不能通过js获得该cookie的值,实际场景根据自身需要
});
#endregion
}
注册服务后,需要在ConfigConfigure使用,注意所有的Use要在UserMvc之前才能生效。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//…之前的代码
app.UseSession();//这里使用
app.UseHttpsRedirection();
app.UseMvc();
}
在Util创建一个SessionUtil,来封装Session方法,这里只简单描述下如何使用,后续代码开源后可查看源码使用。
public class SessionUtil
{
/// <summary>
/// 设置Session
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
public void SetSession(HttpContext content,string key, string value)
{
content.Session.SetString(key, value);
}
/// <summary>
/// 获取Session
/// </summary>
/// <param name="key">键</param>
/// <returns>返回对应的值</returns>
public string GetSession(HttpContext context, string key, string defaultValue = "")
{
string value = context.Session.GetString(key);
if (string.IsNullOrEmpty(value))
{
value = defaultValue;
}
return value;
}
}
我们依然拿这个万恶的ValuesController开刀。

运行后,访问这个Values/{id}接口,发现我们的Session值已经获取到了。

HttpContext这个对象,可以通过IServiceProvider来获取,这样方便调用统一维护。
新建AprilConfig类文件,代码如下:
public class AprilConfig
{
public static IServiceProvider _provider;
public static HttpContext HttpCurrent
{
get
{
object factory = _provider.GetService(typeof(IHttpContextAccessor));
HttpContext context = ((IHttpContextAccessor)factory).HttpContext;
return context;
}
}
}
写好后我们需要回到Startup.cs,给IserviceProvider赋值。

SessionUtil代码修改调整,不需要再传HttpContext这个参数。

这样少传一个是一个,后续用到HttpContext这个上下文的时候,也不用考虑啥了,直接AprilConfig.HttpCurrent走起。
Cookie
Cookie在web开发使用的还是相当频繁的,毕竟不占用服务器内存,跟服务器基本上没半毛钱关系,客户端的内存想咋折腾咋折腾,客户端的资源想咋使用咋使用(ps:这就是为啥你的电脑越来越卡,软件开发不考虑性能优化的种种结果)。
Cookie本身在net core中已经支持,所以不需要引入啥NuGet包。
新建CookieUtil(不要吐槽我的命名方法,习惯了)。
public class CookieUtil
{
/// <summary>
/// 设置本地cookie
/// </summary>
/// <param name="key">键</param>
/// <param name="value">值</param>
/// <param name="minutes">过期时长,单位:分钟</param>
public static void SetCookies(string key, string value, int minutes = 10)
{
AprilConfig.HttpCurrent.Response.Cookies.Append(key, value, new CookieOptions
{
Expires = DateTime.Now.AddMinutes(minutes)
});
}
/// <summary>
/// 删除指定的cookie
/// </summary>
/// <param name="key">键</param>
public static void DeleteCookies(string key)
{
//这个地方想判断就判断下,不过内部封装的方法应该是已经做过处理
AprilConfig.HttpCurrent.Response.Cookies.Delete(key);
}
/// <summary>
/// 获取cookies
/// </summary>
/// <param name="key">键</param>
/// <returns>返回对应的值</returns>
public static string GetCookies(string key,string defaultValue="")
{
string value = string.Empty;
AprilConfig.HttpCurrent.Request.Cookies.TryGetValue(key, out value);
if (string.IsNullOrEmpty(value))
{
value = defaultValue;
}
return value;
}
}
写好之后,老规矩ValuesController走一波。

测试结果:

小结
从创建工程到在线文档,日志管理,缓存机制基本上走了一遍了,下一步,就是数据层的操作,一个工程管理肯定少不了数据的支撑,总不能每次都自己YY数据吧,下一节,数据库操作。
补充
针对Session.SetString的方法没有问题,需要引入一个NuGet包,这个里面包含官方的扩展方法,Microsoft.AspNetCore.Http.Abstractions。
net core Webapi基础工程搭建(五)——缓存机制的更多相关文章
- net core Webapi基础工程搭建(六)——数据库操作_Part 1
目录 前言 SqlSugar Service层 BaseService(基类) 小结 前言 后端开发最常打交道的就是数据库了(静态网站靠边),上一篇net core Webapi基础工程搭建(五)-- ...
- net core Webapi基础工程搭建(六)——数据库操作_Part 2
目录 前言 开始 使用 小结 前言 昨天是写着写着发现,时间不早了,已经养成了晚上下班抽时间看看能写点儿啥的习惯(貌似),今天实在是不想让昨天没做完的事情影响,所以又坐下,沉下心(周末了),开始把数据 ...
- net core Webapi基础工程搭建(七)——小试AOP及常规测试_Part 2
目录 前言 引入 自定义属性 测试 小结 前言 前一篇讲到了中间层的使用,可能不是那么AOP,今天主要来说下一个轻量级的AOP第三方类库AspectoCore. 简单介绍下这个类库,AspectCor ...
- net core Webapi基础工程搭建(四)——日志功能log4net
目录 前言 log4net 依然是,NuGet引用第三方类库 整合LogUtil 小结 前言 一个完整的项目工程离不开日志文件的记录,而记录文件的方法也有很多,可以自己通过Stream去实现文件的读写 ...
- net core Webapi基础工程搭建(二)——创建工程
目录 前言 创建工程 工程文件概述(个人理解) 运行 小结 前言 前面介绍了开发工具及net core版本,后端工程的框架结构开发工具及环境,因为是基础工程,所以没考虑太复杂的框架,如果有架构师请勿喷 ...
- net core Webapi基础工程搭建(七)——小试AOP及常规测试_Part 1
目录 前言 拦截器 异常拦截器 测试结果 身份验证拦截器 测试 小结 补充 2019-07-31 前言 一天天不知道怎么过的,但确实挺忙,事赶事不带停那种,让我感觉跟在流水线干活一样,忙活的事差不多了 ...
- net core Webapi基础工程搭建(一)——开发工具及环境
目录 开发工具 版本 后端框架 开发工具 Visual Studio 2019,既然要折腾那就体验最新版的开发工具有什么特殊的地方,之前个人开发使用的是2017. 下载地址:https://visua ...
- net core Webapi基础工程搭建(三)——在线接口文档Swagger
目录 前言 Swagger NuGet引用第三方类库 别急,还有 没错,注释 小结 前言 前后分离的好处,就是后端埋头做业务逻辑功能,不需要过多考虑用户体验,只专注于数据.性能开发,对于前端需要的数据 ...
- .Net Core3.0 WebApi 项目框架搭建 五: 轻量型ORM+异步泛型仓储
.Net Core3.0 WebApi 项目框架搭建:目录 SqlSugar介绍 SqlSugar是国人开发者开发的一款基于.NET的ORM框架,是可以运行在.NET 4.+ & .NET C ...
随机推荐
- 重新认识 async/await 语法糖
提起.Net中的 async/await,相信很多.neter 第一反应都会是异步编程,其本质是语法糖,但继续追查下去,既然是语法糖,那么经过编译之后,真正的代码是什么样的,如何执行的?带着这些疑问, ...
- CF39D Cubical Planet-C++
银河系中没有你找不到的东西!有一颗形状为立方体的的行星正在绕着一颗形状为二十面体的恒星运转.现在我们让这颗行星的两个在同一条体对角线上的顶点置于(0,0,0)和(1,1,1)上.有两只苍蝇住在行星上. ...
- Baozi Leetcode Solution 205: Isomorphic Strings
Problem Statement Given two strings s and t, determine if they are isomorphic. Two strings are isomo ...
- 博客一键保存本地exe可视化界面文件
说明 非常感谢nick老师的提点老师博客:https://home.cnblogs.com/u/nickchen121/ 项目连接 1.码云:https://gitee.com/wjup/html_t ...
- C语言入门9-1-分类函数
分类函数 ASCII字符可以分为英文字母.数字.控制字符.空白字符.大小写字母以及标点符号,分类是指对字符进行属性判定,判断字符属于哪些范畴,这些属性的判定在程序中非常常见,尤其是通信协议的字符处理部 ...
- Android解决RecyclerView中的item显示不全方案
最近的项目中实现订单确定页面.需要使用ScrollView嵌套RecyclerView,当RecyclerView中的item数量比较多时,就会出现item只显示一部分数据,并没有将用户勾选的商品数量 ...
- SQL server 2014使用导出数据为Excel
1.打开SQL server 2014,连接至数据库引擎 2.在要导出的数据库上右击,选择"任务->导出数据" 3.数据源选择"SQL Server Native ...
- Linux 下实践 VxLAN
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 来源:ht ...
- mybatis01-1测试
首先需要数据源信息和日志文件 然后一个SQLMapConfig.xml配置文件连接数据库并且映射后一个xml文件,另一个xml文件写入SQL语句, 最后text测试文件读取第一个配置文件,放到SQLS ...
- 1A2B
玩了玩www.syscan.org的小游戏,第三关是一个1A2B的问题,写个小脚本爆破一波,同时分享下脚本(把数固定到代码里了,要在别处用的自己改吧). #-*-coding:utf8;-*- #qp ...