麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

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

解讀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)        {
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久国产精品99国产 | 亚洲午夜在线 | 日本一区二区在线 | 久久九九热re6这里有精品 | 麻豆视频免费网站 | 毛片在线免费观看网址 | 亚洲va国产va | 成人羞羞视频在线观看免费 | 91精品成人福利在线播放 | 成人在线精品视频 | 色操网 | 玩偶姐姐在线观看免费 | 99麻豆久久久国产精品免费 | 欧美亚洲国产成人综合在线 | 免费黄色一级网站 | 久久青草影院 | 色吧综合网| 日本a在线观看 | 91麻豆精品国产91久久久点播时间 | 久久久综合久久久 | 精品一区二区三区在线观看视频 | 欧美日韩在线视频一区二区 | 高清国产午夜精品久久久久久 | 激情宗合网 | 欧美一级黄色录像片 | 久久午夜神器 | 国产精品久久久久国产精品三级 | 7777在线观看 | 黄视频免费在线观看 | 成人444kkkk在线观看 | 日韩视频1| 模特三级在线观看 | 欧美日韩在线视频观看 | 国产亚洲精品综合一区91 | 韩国草草影院 | 国产精品成人一区二区三区电影毛片 | 韩国精品一区二区三区四区五区 | 99在线啪 | 国产一区二区三区四区波多野结衣 | av免费在线观看国产 | 久久伊人国产精品 |