本文转自: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. 独立线程监控配置文件是否变更,适用于更新了配置文件,不需要重启tomcat服务

    直接贴出来代码: package cn.leadeon.utils.file; import java.io.File; import java.io.FileInputStream; import ...

  2. NSSet集合

    前言 NSSet:集合 NSSet 集合跟数组差不多,但 Set 集合不能存放相同的对象,它是一组单值对象的集合,被存放进集合中的数据是无序的,它可以是可变的,也可以是不变的. Xcode 7 对系统 ...

  3. vue2.0使用ES6语法

    ES6 快速入门 什么是ES6? ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.Mozilla公司将在这个标准的基础上,推出Java ...

  4. samba服务器架设

    #samba服务器架设方便线上linux服务器和windows服务器之间共享 1.关闭防火墙service iptables stop 2.关闭SELinuxsetenforce 0 3.安装samb ...

  5. Android Gradle 隐形依赖的奇怪案例

    相信 Android 开发者都有在 Android Studio 中升级 compileSdkVersion 的经历,这个时候如果你使用了 support 包,并同时升级,那么可能会出现一个错误提示. ...

  6. Python获取网页Html文本

    Python爬虫基础 1.获取网页文本 通过urllib2包,根据url获取网页的html文本内容并返回 #coding:utf-8 import requests, json, time, re, ...

  7. c语言数据结构学习心得——排序

    排序:将无序的序列重新排列为有序的序列. 插入类排序 插入类排序:在一个有序的序列中,插入一个新的关键字,知道所有的关键字都插入形成一个有序的序列. 直接插入排序:首先以一个元素为有序的序列,然后将后 ...

  8. ubuntu 18.04 通过联网方式安装wine

    ubuntu 18.04 通过联网方式安装wine 1.如果是64位机器,先开启允许32位架构程序运行 sudo dpkg --add-architecture i386 2.添加元wine源码安装仓 ...

  9. 关于执行webdriver.Chrome; 报错WebDriverException: Message: unknown error: Element is not clickable at point (1085, 103)

    from selenium import webdriverfrom time import sleep dr = webdriver.Chrome() dr.get("http://pj1 ...

  10. 构建docker镜像

    一.通过docker commit命令构建镜像 docker commit 构建镜像可以想象为是将运行的镜像进行重命名另存一份.我们先创建一个容器,并在容器里做出修改,就像修改代码一样,最后再将修改提 ...