一. 简介

  关于Session的原理可参照Asp.Net版本Session的文章,去查阅。

1. 普通用法

 (1).通过Nuget引入【Microsoft.AspNetCore.Http】程序集,Core Mvc中已经默认引入了,在哪使用using一下即可。

 (2).注入Session相关的服务。

  A:在ConfigureService注册基于服务器内存的Session, services.AddDistributedMemoryCache(); services.AddSession(); 在Configure中进行启用Session,app.UseSession();

    注:一定要在mvc前面进行注入,进程外Session的注入后面介绍。

  B:如果项目中使用了CookiePolicyOptions,一定要将里面true改为false,如: options.CheckConsentNeeded = context => false; 或者配置Session的性质,options.Cookie.IsEssential = true;(表示cookie是必须的),否则chrome中拿不到Session值

 解释:这是个GDRP条例,让用户自己选择使用用cookie,详见 http://www.zhibin.org/archives/667 或 https://www.cnblogs.com/GuZhenYin/p/9154447.html

  C:在控制器中通过 HttpContext.Session 来向Session中读写各种值。

注册和启用相关的代码:

  public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false; //改为false或者直接注释掉,上面的Session才能正常使用
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//注册Session服务
//基于内存的Session
services.AddDistributedMemoryCache();
//默认过期时间为20分钟,每次访问都会重置
services.AddSession(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
//启用Session管道
app.UseSession(); app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=CoreSession}/{action=Index6}/{id?}");
});
}

测试代码:

       public IActionResult Index()
{
string userName = HttpContext.Session.GetString("userName");
if (string.IsNullOrEmpty(userName))
{
userName = "ypf";
HttpContext.Session.SetString("userName", userName);
}
var t1 = HttpContext.Session.GetString("userName");
ViewBag.userName = userName;
return View();
} public IActionResult Index2()
{
string userName = HttpContext.Session.GetString("userName");
ViewBag.userName = userName;
return View();
}

补充Session默认提供的方法:

2. 全局注册使用

(1).背景:通常便于管理,我们将Session进行全局统一注入,方便管理。

(2).步骤:

  A: 在普通用法的前提下,在ConfigureService中进行统一对象的注册, services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

  B:在控制器利用构造函数进行注入。

  C:正常使用即可,案例详见项目的Index3和Index4

代码分享:

  public class CoreSessionController : Controller
{
private readonly IHttpContextAccessor httpContextAccessor; private ISession MySession => httpContextAccessor.HttpContext.Session; public CoreSessionController(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
#region 02-测试统一注入的用法
/// <summary>
/// 下面是统一注入使用的写法
/// </summary>
/// <returns></returns> public IActionResult Index3()
{
string userName = MySession.GetString("userName");
if (string.IsNullOrEmpty(userName))
{
userName = "ypf";
MySession.SetString("userName", userName);
}
var t1 = MySession.GetString("userName");
ViewBag.userName = userName;
return View();
} public IActionResult Index4()
{
string userName = MySession.GetString("userName");
ViewBag.userName = userName;
return View();
}
#endregion }

二. 高级

1. Session的扩展

(1).背景

  我们发现系统默认提供的Session方法,仅能存储byte、string、int类型,很不灵活,我们想能存储任何对象,这个时候就需要我们自行扩展。 对SessionExtensions类进行扩展

(2).利用Newtonsoft.Json进行扩展

  A. 扩展代码详见SessionExtensions中的Set和Get方法

  B. 案例详见Index5

(3).利用protobuf-net进行扩展

  A. 通过Nuget安装程序集【protobuf-net】,这是谷歌的一个程序集,序列化和反序列效率更高

  B. 扩展代码详见SessionExtensions中的Set2和Get2方法, 如果写入的是个类,类名上要加 [ProtoContract],属性上要加 [ProtoMember(1)] [ProtoMember(2)]等等, 如:UserInfor2

  C. 案例详见Index6

扩展代码:

   public static class SessionExtensions
{
#region 01-利用Newtonsoft.Json进行扩展
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
} public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
#endregion #region 02-利用protobuf-net进行扩展
public static void Set2<T>(this ISession session, string key, T value)
{
using (MemoryStream stream = new MemoryStream())
{
Serializer.Serialize(stream, value);
byte[] byteArrary = stream.ToArray();
session.Set(key, byteArrary);
}
} public static T Get2<T>(this ISession session, string key)
{
byte[] byteArray = session.Get(key);
if (byteArray == null)
{
return default(T);
}
else
{
using (MemoryStream stream = new MemoryStream(byteArray))
{
return Serializer.Deserialize<T>(stream);
}
}
}
#endregion
}

类代码:

  public class UserInfor1
{
public string id { get; set; }
public string userName { get; set; }
}
[ProtoContract]
public class UserInfor2
{
[ProtoMember()]
public string id { get; set; }
[ProtoMember()]
public string userName { get; set; } }

测试代码:

   #region 03-测试Newtonsoft.Json进行扩展
public IActionResult Index5()
{
UserInfor1 user = HttpContext.Session.Get<UserInfor1>("u1");
if (user == null)
{
user = new UserInfor1();
user.id = "";
user.userName = "Marren";
HttpContext.Session.Set<UserInfor1>("u1", user);
}
ViewBag.id = user.id;
ViewBag.userName = user.userName;
return View();
}
#endregion #region 04-测试protobuf-net进行扩展
public IActionResult Index6()
{
UserInfor2 user = HttpContext.Session.Get2<UserInfor2>("u2");
if (user == null)
{
user = new UserInfor2();
user.id = "";
user.userName = "Marren";
HttpContext.Session.Set2<UserInfor2>("u2", user);
}
ViewBag.id = user.id;
ViewBag.userName = user.userName;
return View();
}
#endregion

2.Session的性质

(1). Session的过期时间(多次访问将会被重置,默认过期时间为20分钟)

  如:options.IdleTimeout = TimeSpan.FromMinutes(120);

(2). 设置为true表示前端js等脚本无法读取cookie,防止了xss攻击(默认是true)

  如:options.Cookie.HttpOnly = true;

(3). Cookie是必须的(默认是false),可以覆盖上面的cookie策略

  如:options.Cookie.IsEssential = true;

3. 如何在普通类中使用Session对象?

(1).说明

  再普通类中如何调用Session,大约有两种思路:以构造函数的注入进去,但是如果这个类不是过滤器,使用的时候就需要实例化,又需要传入对象进去,如CheckLogin类,很麻烦,所以建议用第二种方案,直接吧实例好的Session传入进去,直接使用即可,如CheckLogin2.

(2). 方案一

  先统一注入, services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();,然后再在控制器中进行构造函数注入,但调用的时候还需要传入进去。

PS:过滤器中可以直接context.httpContext.Session来设置

(3). 方案二

  直接把实例好的Session传进去

  public class CheckLogin2
{
private ISession MySession { get; set; } public CheckLogin2(ISession mySession)
{
MySession = mySession;
}
public bool isLogin()
{
string userName = MySession.GetString("userName");
if (string.IsNullOrEmpty(userName))
{
return false;
}
return true;
}
}

三. 进程外Session

   关于进程外Session的好处、解决了什么痛点问题,可以参考Asp.Net 中的进程外Session,去查阅。 (解决了IIS重启Session丢失的问题,解决了Session空间有限容易被挤爆的问题,但不能解决浏览器重启找不到Session的问题!)

  特别说明:基于SQLServer或Redis数据的进程外Session 的数据库方面的配置和前面分布式缓存章节数据库的配置完全相同,去查阅。

1. 基于SQLServer

(1). 安装【Microsoft.Extensions.Caching.SqlServer】程序集,如果是Core MVC程序,自带的Microsoft.AspNetCore.App包里已经涵盖了该程序集,无需重复安装。

(2). 首先要有个目标数据库中(比如CacheDB数据库),然后以管理员身份cmd运行下面指令,会创建一张名叫“AspNetCoreSession”表,相应的Session信息都存在于这张表中。

【dotnet sql-cache create "Server=localhost;User=sa;Password=123456;Database=CacheDB" dbo AspNetCoreSession】成功后会提示:Table and index were created successfully.

PS:补充表的结构和含义, 分别是键、值、到期时刻(有问题)、滑动过期时间、绝对过期时间。

(3). 将原先基于内存的Session代码( services.AddDistributedMemoryCache(); )替换成基于SqlServer的代码,如下:

             //01-基于内存的Session
//services.AddDistributedMemoryCache(); //02-基于SQLServer的Session
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = Configuration["SqlSeverConnectionString"];
options.SchemaName = "dbo";
options.TableName = "AspNetCoreSession";
});
 {
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"SqlSeverConnectionString": "Server=localhost;User=sa;Password=123456;Database=CacheDB"
}

(4). 其它的配置都不变,正常使用即可。

2. 基于Redis

(1). 安装【Microsoft.Extensions.Caching.StackExchangeRedis】程序集,Core MVC中这个也是不包含的。

(2). 下载Redis程序,打开redis-server.exe,启动Redis。

(3). 将原先基于内存的Session代码 ( services.AddDistributedMemoryCache(); ) 替换成基于Redis的代码,如下:

            //01-基于内存的Session
//services.AddDistributedMemoryCache(); //03-基于Redis的Session
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});

(4). 其它配置都不变,正常使用即可。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第十六节:Asp.Net Core中Session的使用、扩展、进程外Session的更多相关文章

  1. [EXTJS5学习笔记]第二十六节 在eclipse/myeclipse中使用sencha extjs的插件

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/40507383 插件下载: http://download.csdn.net/detai ...

  2. 第二十九节: Asp.Net Core零散获取总结(不断补充)

    1. IWebHostEnvironment获取常用属性 (1).获取项目的根目录 _env.ContentRootPath 等价于 Directory.GetCurrentDirectory() ( ...

  3. 在ASP.NET Core中用HttpClient(六)——ASP.NET Core中使用HttpClientFactory

    ​到目前为止,我们一直直接使用HttpClient.在每个服务中,我们都创建了一个HttpClient实例和所有必需的配置.这会导致了重复代码.在这篇文章中,我们将学习如何通过使用HttpClient ...

  4. [08]ASP.NET Core 中 launchsettings.json 启动配置文件

    ASP.NET Core launchsettings.json 启动配置文件 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自 ...

  5. 第十五节:Asp.Net Core中的各种过滤器(授权、资源、操作、结果、异常)

    一. 简介 1. 说明 提到过滤器,通常是指请求处理管道中特定阶段之前或之后的代码,可以处理:授权.响应缓存(对请求管道进行短路,以便返回缓存的响应). 防盗链.本地化国际化等,过滤器用于横向处理业务 ...

  6. 第十四节:Asp.Net Core 中的跨域解决方案(Cors、jsonp改造、chrome配置)

    一. 整体说明 1. 说在前面的话 早在前面的章节中,就详细介绍了.Net FrameWork版本下MVC和WebApi的跨域解决方案,详见:https://www.cnblogs.com/yaope ...

  7. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  8. 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础

    第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...

  9. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

随机推荐

  1. Redis基本使用(一)

    redis window系统的redis是微软团队根据官方的linux版本高仿的 官方原版: https://redis.io/ 中文官网:http://www.redis.cn 1 redis下载和 ...

  2. make几个知识点

    即时变量和延时变量 在下面代码中,定义了一个值为x的x变量,以延时变量的方式将它的值赋给y,以即时变量的方式将它的值赋给z. 因为y为延时变量,所以y的取值并不会立即计算,而是在整个文件解析完成之后才 ...

  3. 爬取 豆瓣电影Top250

    目标 学习爬虫,爬豆瓣榜单,获取爬取静态页面信息的能力 豆瓣电影 Top 250  https://movie.douban.com/top250 代码 import requests from bs ...

  4. mysql数据库之事务和隔离级别

    事务和并发执行目的: 1.提高吞吐量,资源利用率 2.减少等待时间 连接管理器:接受请求/创建线程/认证用户/建立安全连接 并发控制:任何时候,只要有两个以上的用户试图读写同时一个文件/数据,都会带来 ...

  5. 前后端分离-Restful最佳实践

    前后端分离-Restful最佳实践 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任.

  6. Leetcode——2. 两数相加

    难度: 中等 题目 You are given two non-empty linked lists representing two non-negative integers. The digit ...

  7. Ubuntu16.04下Python2:pip安装opendr库

    在Ubuntu16.04/Python2环境安装opendr遇到了问题,并且报错不清楚. 使用dis_to_free的方法很好地解决问题. sudo apt install libosmesa6-de ...

  8. iOS-快速开发直播APP所需第三方SDK

    直播SDK 金山云, 推荐 七牛云, 推荐 阿里云(收费) 网易云(收费) 腾讯云(收费) 又拍云 播放SDK IJKPlayer 自定义IJKPlayer,进度条.音量.亮度 短视频SDK 七牛云( ...

  9. Alibaba Cloud SDK for Java,知识点

    资料 网址 Alibaba Cloud SDK for Java https://help.aliyun.com/document_detail/52740.html?spm=a2c4g.111742 ...

  10. nginx 跨域请求访问

    1.nginx跨域请求访问 location ~ .*\.(htm|html)$ { add_header Access-Control-Allow-Origin(请求域名) *(所有域名) http ...