本文转自: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. 转载:ResultMap和ResultType在使用中的区别

    在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap,下面说下我对这两者的认识和理解 resultType:当使 ...

  2. 模态显示PresentModalViewController

    1.主要用途 弹出模态ViewController是IOS变成中很有用的一个技术,UIKit提供的一些专门用于模态显示的ViewController,如UIImagePickerController等 ...

  3. 「BZOJ 2733」「HNOI 2012」永无乡「启发式合并」

    题意 你需要维护若干连通快,有两个操作 合并\(x,y\)所在的连通块 询问\(x\)所在连通块中权值从小到大排第\(k\)的结点编号 题解 可以启发式合并\(splay\),感觉比较好些的 一个连通 ...

  4. C#质因子(自己别扭的逻辑。。)

    static int length1(int num) //想着要定义一个函数取,质因子数组的长度 { ; ; i <= num; i++) //for循环中I 不会归零 只能遍历一次 { if ...

  5. Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)

    #include<bits/stdc++.h>using namespace std;int st[1000007];int top;int s[1000007],t[1000007];i ...

  6. 重写成员“MySql.Data.Entity.MySqlConnectionFactory.CreateConnection(System.String)”时违反了继承安全性规则。重写方法的安全可访问性必须与所重写方法的安全可访问性匹配。

      1,程序中使用加载反射出现下面的问题: 无法加载一个或多个请求的类型.有关更多信息,请检索 LoaderExceptions 属性. 然后把代码改了一下, try { types.AddRange ...

  7. 6. 重点来啦,pytest的各种装饰圈fixtures

    pytest中,fixture的目的是什么 为可靠的和可重复执行的测试提供固定的基线.(可以理解为测试的固定配置,使不同范围的测试都能够获得统一的配置.) fixture提供了区别于传统单元测试(se ...

  8. css3中的display:-webkit-box的用法

    一. css weui-media-box__desc { color: #999999; font-size: 13px; line-height: 1.2; overflow: hidden; t ...

  9. 安装opencv-python

    1.安装包下载:在下面的网址下载对应版本及平台的 .whl 包,再手动安装. https://www.lfd.uci.edu/~gohlke/pythonlibs/ 2.将其拷贝到 Python 目录 ...

  10. 洛谷P2800 又上锁妖塔

    放题解 题目传送门 放代码