亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

解讀ASP.NET 5 & MVC6系列(8):Session與Caching

2019-11-17 02:06:36
字體:
來源:轉載
供稿:網友

解讀asp.net 5 & MVC6系列(8):session與Caching

2015-05-21 09:08 by 湯姆大叔, ... 閱讀, ... 評論, 收藏, 編輯

在之前的版本中,Session存在于System.Web中,新版ASP.NET 5中由于不在依賴于System.Web.dll庫了,所以相應的,Session也就成了ASP.NET 5中一個可配置的模塊(middleware)了。

配置啟用Session

ASP.NET 5中的Session模塊存在于Microsoft.AspNet.Session類庫中,要啟用Session,首先需要在PRoject.json中的dependencies節點中添加如下內容:

"Microsoft.AspNet.Session": "1.0.0-beta3"

然后在ConfigureServices中添加Session的引用(并進行配置):

services.AddCaching();  // 這兩個必須同時添加,因為Session依賴于Cachingservices.AddSession();//services.ConfigureSession(null); 可以在這里配置,也可以再后面進行配置

最后在Configure方法中,開啟使用Session的模式,如果在上面已經配置過了,則可以不再傳入配置信息,否則還是要像上面的配置信息一樣,傳入Session的配置信息,代碼如下:

app.UseInMemorySession(configure:s => { s.IdleTimeout = TimeSpan.FromMinutes(30); });//app.UseSession(o => { o.IdleTimeout = TimeSpan.FromSeconds(30); });//app.UseInMemorySession(null, null);   //開啟內存Session//app.UseDistributedSession(null, null);//開啟分布式Session,也即持久化Session//app.UseDistributedSession(new RedisCache(new RedisCacheOptions() { Configuration = "localhost" }));

對于UseInMemorySession方法,接收2個可選參數,分別是:IMemoryCache可用于修改Session數據的默認保存地址;Action<SessionOptions>委托則可以讓你修改默認選項,比如Session cookie的路徑、默認的過期時間等。本例中,我們修改默認過期時間為30分鐘。

注意:該方法必須在app.UseMvc之前調用,否則在Mvc里獲取不到Session,而且會出錯。

獲取和設置Session

獲取和設置Session對象,一般是在Controller的action里通過this.Context.Session來獲取的,其獲取的是一個基于接口ISessionCollection的實例。該接口可以通過索引、Set、TryGetValue等方法進行Session值的獲取和設置,但我們發現在獲取和設置Session的時候,我們只能使用byte[]類型,而不能像之前版本的Session一樣可以設置任意類型的數據。原因是因為,新版本的Session要支持在遠程服務器上存儲,就需要支持序列化,所以才強制要求保存為byte[]類型。所以我們在保存Session的時候,需要將其轉換為byte[]才能進行保存,并且獲取以后要再次將byte[]轉換為自己的原有的類型才行。這種形式太麻煩了,好在微軟在Microsoft.AspNet.Http命名空間(所屬Microsoft.AspNet.Http.Extensions.dll中)下,為我們添加了幾個擴展方法,分別用于設置和保存byte[]類型、int類型、以及string類型,代碼如下:

public static byte[] Get(this ISessionCollection session, string key);public static int? GetInt(this ISessionCollection session, string key);public static string GetString(this ISessionCollection session, string key);public static void Set(this ISessionCollection session, string key, byte[] value);public static void SetInt(this ISessionCollection session, string key, int value);public static void SetString(this ISessionCollection session, string key, string value);

所以,在Controller里引用Microsoft.AspNet.Http命名空間以后,我們就可以通過如下代碼進行Session的設置和獲取了:

Context.Session.SetString("Name", "Mike");Context.Session.SetInt("Age", 21);ViewBag.Name = Context.Session.GetString("Name");ViewBag.Age = Context.Session.GetInt("Age");

自定義類型的Session設置和獲取

前面我們說了,要保存自定義類型的Session,需要將其類型轉換成byte[]數組才行,在本例中,我們對bool類型的Session數據進行設置和獲取的代碼,示例如下:

public static class SessionExtensions{    public static bool? GetBoolean(this ISessionCollection session, string key)    {        var data = session.Get(key);        if (data == null)        {            return null;        }        return BitConverter.ToBoolean(data, 0);    }     public static void SetBoolean(this ISessionCollection session, string key, bool value)    {        session.Set(key, BitConverter.GetBytes(value));    }}

定義bool類型的擴展方法以后,我們就可以像SetInt/GetInt那樣進行使用了,示例如下:

Context.Session.SetBoolean("Liar", true);ViewBag.Liar = Context.Session.GetBoolean("Liar");

另外,ISessionCollection接口上還提供了Remove(string key)和Clear()兩個方法分別用于刪除某個Session值和清空所有的Session值的功能。但同時也需要注意,該接口并沒提供之前版本中的Abandon方法功能。

基于Redis的Session管理

使用分布式Session,其主要工作就是將Session保存的地方從原來的內存換到分布式存儲上,本節,我們以Redis存儲為例來講解分布式Session的處理。

先查看使用分布式Session的擴展方法,示例如下,我們可以看到,其Session容器需要是一個支持IDistributedCache的接口示例。

public static IapplicationBuilder UseDistributedSession([NotNullAttribute]this IApplicationBuilder app, IDistributedCache cache, Action<SessionOptions> configure = null);

該接口是緩存Caching的通用接口,也就是說,只要我們實現了緩存接口,就可以將其用于Session的管理。進一步查看該接口發現,該接口中定義的Set方法還需要實現一個ICacheContext類型的緩存上下文(以便在調用的時候讓其它程序進行委托調用),接口定義分別如下:

public interface IDistributedCache{    void Connect();    void Refresh(string key);    void Remove(string key);    Stream Set(string key, object state, Action<ICacheContext> create);    bool TryGetValue(string key, out Stream value);}public interface ICacheContext{    Stream Data { get; }    string Key { get; }    object State { get; }    void SetAbsoluteExpiration(TimeSpan relative);    void SetAbsoluteExpiration(DateTimeOffset absolute);    void SetSlidingExpiration(TimeSpan offset);}

接下來,我們基于Redis來實現上述功能,創建RedisCache類,并繼承IDistributedCache,引用StackExchange.Redis程序集,然后實現IDistributedCache接口的所有方法和屬性,代碼如下:

using Microsoft.Framework.Cache.Distributed;using Microsoft.Framework.OptionsModel;using StackExchange.Redis;using System;using System.IO;namespace Microsoft.Framework.Caching.Redis{    public class RedisCache : IDistributedCache    {        // KEYS[1] = = key        // ARGV[1] = absolute-expiration - ticks as long (-1 for none)        // ARGV[2] = sliding-expiration - ticks as long (-1 for none)        // ARGV[3] = relative-expiration (long, in seconds, -1 for none) - Min(absolute-expiration - Now, sliding-expiration)        // ARGV[4] = data - byte[]        // this order should not change LUA script depends on it        private const string SetScript = (@"                redis.call('HMSET', KEYS[1], 'absexp', ARGV[1], 'sldexp', ARGV[2], 'data', ARGV[4])                if ARGV[3] ~= '-1' then                  redis.call('EXPIRE', KEYS[1], ARGV[3])                 end                return 1");        private const string AbsoluteExpirationKey = "absexp";        private const string SlidingExpirationKey = "sldexp";        private const string DataKey = "data";        private const long NotPresent = -1;        private ConnectionMultiplexer _connection;        private IDatabase _cache;        private readonly RedisCacheOptions _options;        private readonly string _instance;        public RedisCache(IOptions<RedisCacheOptions> optionsaccessor)        {            _options = optionsAccessor.Options;            // This allows partitioning a single backend cache for use with multiple apps/services.            _instance = _options.InstanceName ?? string.Empty;        }        public void Connect()        {            if (_connection == null)            {                _connection = ConnectionMultiplexer.Connect(_options.Configuration);                _cache = _connection.GetDatabase();            }        }        public Stream Set(string key, object state, Action<ICacheContext> create)        {            Connect();            var context = new CacheContext(key) { State = state };            create(context);            var value = context.GetBytes();            var result = _cache.ScriptEvaluate(SetScript, new RedisKey[] { _instance + key },                new RedisValue[]                {                    context.AbsoluteExpiration?.Ticks ?? NotPresent,                    context.SlidingExpiration?.Ticks ?? NotPresent,                    context.GetExpirationInSeconds() ?? NotPresent,                    value                });            // TODO: Error handling            return new MemoryStream(value, writable: false);        }        public bool TryGetValue(string key, out Stream value)        {            value = GetAndRefresh(key, getData: true);            return value != null;        }        public void Refresh(string key)        {
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久久粉嫩av| 欧美色图在线视频| 久久九九全国免费精品观看| 粉嫩av一区二区三区免费野| 欧美电影免费播放| 亚洲一区二区中文| 日韩久久午夜影院| 91成人在线播放| 2018中文字幕一区二区三区| 中文字幕免费国产精品| 国产91精品青草社区| 国产成人精品视频在线| 亚洲高清av在线| 国产日韩在线看片| 亚洲全黄一级网站| 91免费在线视频| 九九热视频这里只有精品| 久久久久久久激情视频| 久久五月情影视| 视频在线观看一区二区| 久热在线中文字幕色999舞| 欧美日韩福利在线观看| 日韩有码片在线观看| 日韩最新中文字幕电影免费看| 在线电影中文日韩| 亚洲国产日韩欧美综合久久| 亚洲精品v天堂中文字幕| 性欧美暴力猛交69hd| 久久精品福利视频| 国产免费久久av| 欧美专区福利在线| 国产精品揄拍一区二区| 精品欧美aⅴ在线网站| 777午夜精品福利在线观看| 国产精品一区二区久久久| 国产精品2018| 亚洲aaa激情| 国产三级精品网站| 欧美精品在线免费播放| 欧美精品制服第一页| 亚洲人成欧美中文字幕| 国产精品18久久久久久首页狼| www.日韩不卡电影av| 欧美日韩精品在线观看| 欧美影院久久久| 国产综合久久久久| 国产成人精品a视频一区www| 久久香蕉国产线看观看网| 国产精品久久久久久av福利软件| 国产精品福利网| 欧美视频裸体精品| 91亚洲永久免费精品| 国产精品福利在线观看网址| 成人黄色生活片| 色噜噜狠狠狠综合曰曰曰| 国产一区二中文字幕在线看| xvideos国产精品| 日韩av中文字幕在线| 国产欧美精品在线播放| 亚洲人成电影在线播放| 国产精品久久精品| 亚洲欧美在线第一页| 亚洲自拍高清视频网站| 久久久亚洲福利精品午夜| 久久99久久久久久久噜噜| 国产做受高潮69| 91香蕉电影院| 亚洲欧美在线磁力| 欧美日韩午夜视频在线观看| 色婷婷亚洲mv天堂mv在影片| 1769国内精品视频在线播放| 国产精品旅馆在线| 亚洲福利视频网| 97国产精品视频| 欧美成人午夜剧场免费观看| 国产精品久久久久久久7电影| 欧美在线视频一区| 欧美黑人xxx| 国产亚洲精品久久久| 亚洲精品一区av在线播放| 国产一区二区日韩精品欧美精品| 国产999在线| 96国产粉嫩美女| 亚洲黄色在线观看| 欧美激情图片区| 国产精品欧美久久久| 久久精品国产综合| 国产激情久久久| 欧美亚洲国产视频| 在线电影欧美日韩一区二区私密| 国产精品综合网站| 成人精品网站在线观看| 欧美性猛交xxxx久久久| 亚洲国产精品yw在线观看| 成人黄色影片在线| 日韩国产在线播放| 国产精品亚洲精品| 亚洲a成v人在线观看| 激情亚洲一区二区三区四区| 亚洲最新av网址| 日本高清不卡在线| 欧美一区二区三区艳史| 精品视频久久久久久久| 亚洲日本欧美日韩高观看| 精品丝袜一区二区三区| www.欧美免费| 成人亚洲欧美一区二区三区| 日韩国产高清视频在线| 91久久精品日日躁夜夜躁国产| 亚洲精品久久在线| 国产69精品久久久久久| 国产精品18久久久久久首页狼| www.国产一区| 亚洲精品国产精品国自产在线| 日韩大陆欧美高清视频区| 日韩精品一区二区视频| 欧美重口另类videos人妖| 色婷婷久久一区二区| 精品色蜜蜜精品视频在线观看| 日韩在线国产精品| 色偷偷偷亚洲综合网另类| 亚洲国产一区二区三区在线观看| 久久中文字幕视频| 日韩免费高清在线观看| 欧美成人精品一区| 日韩精品久久久久久福利| 中文字幕在线国产精品| 在线电影中文日韩| www.国产精品一二区| 欧美激情奇米色| 欧美高清自拍一区| 欧美在线观看网址综合| 日韩在线视频网站| 欧美激情精品在线| 欧美成人精品三级在线观看| 亚洲国产精品免费| 色偷偷av一区二区三区| 欧美剧在线观看| 最新的欧美黄色| 国产成人精品免高潮费视频| 2024亚洲男人天堂| 国产成+人+综合+亚洲欧洲| 久久九九免费视频| 亚洲网站在线观看| 日韩欧美高清在线视频| 国产欧美亚洲视频| 在线日韩精品视频| 国产精品日韩久久久久| 欧美国产日韩xxxxx| 欧美精品精品精品精品免费| 欧美乱人伦中文字幕在线| 亚洲欧美国产一本综合首页| 黄色一区二区三区| 92版电视剧仙鹤神针在线观看| 在线观看亚洲区| 久久九九国产精品怡红院| 亚洲精品美女免费| 国产精品美乳在线观看| 国内揄拍国内精品少妇国语| 精品国产鲁一鲁一区二区张丽| 国产精品精品视频| 91性高湖久久久久久久久_久久99| 日韩中文有码在线视频| 2020久久国产精品|