本文转自:http://zhuchenglin.me/fundamentals-11-app-state?utm_source=tuicool&utm_medium=referral

ASP.NET Core基本原理(11)-管理应用程序状态[译]

在ASP.NET Core中,应用程序的状态可以有多种方式进行管理,取决于何时以及如何检索状态。

应用程序状态的可选方式

应用程序状态指用于描述应用程序当前状态的任何数据。这包含全局和特定于用户的数据。ASP.NET之前的版本已经有内置的对全局ApplicationSession 状态的支持。

应用程序开发者可以根据不同的因素来自由选择不同的方式存储状态数据:

  • 数据需要持续多长时间?
  • 数据有多大?
  • 数据的格式是什么?
  • 数据是否可以序列化?
  • 数据有多敏感?能不能保存在客户端?

基于这些问题的答案,在ASP.NET Core以不同的方式存储和管理应用程序的状态。

HttpContext.Items

当数据只用于一个给定请求进行处理时,Items集合是存储数据的最佳位置。数据内容将在每个请求结束之后被丢弃。可以作为组件或者中间件在一个请求期间的不同时间点进行通信的最佳手段,并且彼此之间没有直接关系。

QueryString and Post

在新的请求查询字符串中添加值或者通过POSTing数据,可以将一个请求的状态数据提供给另一个请求。这种技术不应该用于敏感性的数据,因为这种技术需要将数据发送给客户端,然后再发送回服务器。也最好用于少量的数据。查询字符串对于持久地保留状态特别有用,允许创建具有嵌入状态的链接并通过Email和社交网络进行发送,没有对做出请求的用户做出假设,因为具有查询字符串的URL可以很容易被分享,所以必须小心避免跨站请求伪装攻击 (Cross-Site Request Forgery, CSRF)(例如,即使假设只有验证的用户才能够使用基于URL的查询字符串,攻击者还是诱骗已经验证过的用户去访问这样的URL)。

Cookies

与状态有关的少量数据可以存储在Cookies中。它们给随每次请求被发送,所以它的大小应该保存最小化。理想情况下,应该只使用一个标识符,而真正的数据存储在服务器中。

Session

Session存储依靠一个基于Cookie的标识符来访问与给定浏览器Session相关的数据(来自一个特定浏览器和机器的一系列请求)。你不能假设一个Session只限定给一个用户。所以要谨慎考虑在Session中存储哪类信息。这是一个很好的地方来存储具体到一个特定Session但不需要持久保存的应用程序状态。

Cache

缓存提供了一种基于开发人员定义的键来存储和有效检索任意应用程序数据的方法。它提供了基于时间和其他因素来使缓存过期的规则。

Configuration

配置可以认为是应用程序状态存储的另一种形式,但是通常它的应用程序运行时是只读的。

使用HttpContext.Items

HttpContext抽象通过Items提供了对一个简单的IDictionary<object, object>类型的字典集合的支持。在每个请求中,这个集合从HttpRequest。你不能假设一个Session只限定给一个用户。所以要谨慎考虑在Session中存储哪类信息。这是一个很好的地方来存储具体到一个特定Session但不需要持久保存的应用程序状态。

例如,一个简单的中间件可以向Items集合中添加一些内容:

app.Use(async (context, next) =>
{
// perform some verification
context.Items["isVerified"] = true;
await next.Invoke();
});

随后,在管道中,其它的中间件可以访问到它:

app.Run(async (context) =>
{
await context.Response.WriteAsync("Verified request? " + context.Items["isVerified"]);
});

安装和配置Session

ASP.NET Core提供了一个会话包,它提供了用于管理会话状态的中间件。你可以在project.json文件中加入对Microsoft.AspNetCore.Session包的引用来安装它。

一旦安装好程序包,必须在Startup类中对Session进行配置。Session是基于IDistributedCache进行构建的,因此也必须配置它,否则你会得到一个错误。

注:如果你一个IDistributedCache实现都没有配置,则会得到一个异常 - “Unable to resolve service for type ‘Microsoft.Extensions.Caching.Distributed.IDistributedCache’ while attempting to activate ‘Microsoft.AspNetCore.Session.DistributedSessionStore’.”

ASP.NET提供了IDistributedCache的多种实现,包含in-memory选项(仅用于开发和测试期间)。要配置Session使用采用in-memory选项,将Microsoft.Extensions.Caching.Memory依赖项添加到你的project.json中,然后再添加如下代码到ConfigureServices:

services.AddDistributedMemoryCache();
services.AddSession();

然后,添加如下代码到Configure,并且添加到app.UseMVC()之前,这样你就可以在程序代码中使用会话了:

app.UseSession();

安装和配置好之后,你就可以从HttpContext中引用Session了。

注:如果你在调用UseSession之前尝试访问Session,你将会得到一个InvalidOperationException异常 - “Session has not been configured for this application or request.”

实现细节

Session是利用一个cookie来跟踪和区分不同浏览器之间的请求的。默认情况下,这个cookie命名为”.AspNet.Session”,并使用一个路径”/”。另外,在默认情况下,这个cookie不指定域,而且对于页面上的客户端脚本是不可使用的(因为CookieHttpOnly的默认值是true)。

这些默认值,以及IdleTimeout(独立于cookie在服务端使用),都可以通过SessionOptions在配置Session的时候重写:

services.AddSession(options =>
{
options.CookieName = ".AdventureWorks.Session";
options.IdleTimeout = TimeSpan.FromSeconds(10);
});

IdleTimeout被服务端用于决定在Session的内容被抛弃之前Session可以闲置多久。每一个请求通过Session中间件(无论中间件对Session是读取还是写入)都将会重置超时时间。注意,这与cookie的过期时间是独立的。

ISession

一旦Session安装和配置完成,你就可以通过HttpContext所暴露的一个ISession类型名为Session的属性来引用它。

public interface ISession
{
bool IsAvailable { get; }
string Id { get; }
IEnumerable<string> Keys { get; }
Task LoadAsync();
Task CommitAsync();
bool TryGetValue(string key, out byte[] value);
void Set(string key, byte[] value);
void Remove(string key);
void Clear();
}

因为Session构建在IDistributedCache之上,你必须总是序列化被存储的对象实例。因此,这个接口使用byte[]而不是直接使用object。不过,有扩展方法可以让使用诸如StringInt32变得更容易。

// session extension usage examples
context.Session.SetInt32("key1", 123);
int? val = context.Session.GetInt32("key1"); context.Session.SetString("key2", "value");
string stringVal = context.Session.GetString("key2"); byte[] result = context.Session.Get("key3");

如果要存储更复杂的对象,你需要把对象序列化为一个byte[]以便存储它们,在获取对象的时候,要将它们从byte[]进行反序列化。

原文链接

Managing Application State

[转]ASP.NET Core基本原理(11)-管理应用程序状态的更多相关文章

  1. ASP.NET Core Basic 1-1 WebHost与项目配置

    .NET Core ASP.NET Core Basic 1-1 本节内容为WebHost与项目配置 项目配置文件 我们可以很清楚的发现在我们的文件中含有一个Json文件--appsettings.j ...

  2. asp.net core 系列 11 配置configuration (下)

    四. 文件配置提供程序AddIniFile. AddXmlFile.AddJsonFile FileConfigurationProvider 是从文件系统加载配置的基类. 以下配置提供程序专用于特定 ...

  3. 菜鸟入门【ASP.NET Core】11:应用Jwtbearer Authentication、生成jwt token

    准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...

  4. 【目录】asp.net core系列篇

    随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...

  5. ASP.NET MVC应用迁移到ASP.NET Core及其异同简介

    ASP.NET Core是微软新推出支持跨平台.高性能.开源的开发框架,相比起原有的ASP.NET来说,ASP.NET Core更适合开发现代应用程序,如跨平台.Dorker的支持.集成现代前端开发框 ...

  6. 理解ASP.NET Core - [03] Dependency Injection

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接 ...

  7. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  8. ASP.NET Core 1.0 中的依赖项管理

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  9. ABP 教程文档 1-1 手把手引进门之 ASP.NET Core & Entity Framework Core(官方教程翻译版 版本3.2.5)

    本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 官方文档分四部分 一. 教程文档 二.ABP 框架 三.zero 模块 四.其他(中文翻译资源) 本篇是第一部分的第一篇. 第一部分分三篇 1- ...

随机推荐

  1. ZooKeeper的部署和测试

    一背景 zookeeper是一个开源的分布式应用程序协调服务,是Apache Hadoop 的一个子项目.它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护.名字服务.分布式同步.组服 ...

  2. C语言条件编译(#if,#ifdef,#ifndef,#endif,#else,#elif)

    1.条件编译介绍 条件编译(conditional compiling)命令指定预处理器依据特定的条件来判断保留或删除某段源代码.例如,可以使用条件编译让源代码适用于不同的目标系统,而不需要管理该源代 ...

  3. day1学python Hello Python

    Hello Python 本人使用的是Pycharm编译器 ----------------------------------------------- 1.输出 2.赋值 3.‘’‘/“”“ 多行 ...

  4. js创建ActiveXObject无效

    是因为使用的浏览器不是ie内核的,比如用搜狗浏览器,切换为兼容模式就正常了

  5. Kubernetes权威指南学习笔记(一)

    https://blog.csdn.net/keysilence1/article/details/70239717 概念 Kubernetes是谷歌严格保密十几年的秘密武器——Borg的一个开源版本 ...

  6. selenium滑动验证码操作

    1.首先要找到你要滑动的地方 2.调动鼠标事件按住不动 3.调整坐标即可 我这里是为了调试加了很多的sleep,print(hander)是为了看是否定位到了元素 4.效果如下图,但是我这里的验证文字 ...

  7. python 第三次作业

    习题1: **1.初始化一个数据集,包括5-10位同学的成绩数据(数据类型不限),数据格式如下: **学号 姓名 Java C语言 Python 2017XXXX 小白 87 68 92 2017XX ...

  8. 洛谷 P4001 [ICPC-Beijing 2006]狼抓兔子

    题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...

  9. java基础(多态)_03

    一.多态 1.概念:一个对象的多种形态 2.前提: a:必须有继承 b:必须有重写(只有重写才会有意义,没重写语法没错) 3.体现形式: 父类类型 变量名 = new 子类类型(): 4.注意事项: ...

  10. 【算法笔记】B1021 个位数统计

    1021 个位数统计 (15 分) 给定一个 k 位整数 N=d​k−1​​10​k−1​​+⋯+d​1​​10​1​​+d​0​​ (0≤d​i​​≤9, i=0,⋯,k−1, d​k−1​​> ...