asp.net Core uses Redis storage session

Source: Internet
Author: User
Tags redis

Http://www.cnblogs.com/hantianwei/p/5723959.html

asp.net Core has changed the previous closure, now open source and open, let's use the Redis storage session to do a simple test, or called middleware (middleware).

For the session is mixed, many people directly say don't use, also have a lot of people in use, this also has no absolute this righteousness, the individual thinks as long as does not shadow what and can facilitate the realization of things can be used, now right can not be used as a gesture, we only care about realization. class Library References

This is a lot more convenient than the previous. NET, and you need to add the following in the Dependencies node in Project.json:

    "Stackexchange.redis": "1.1.604-alpha", "
    Microsoft.AspNetCore.Session": "1.1.0-alpha1-21694"
Redis Implementation

This is not my realization, but to borrow https://github.com/aspnet/Caching/tree/dev/src/ Microsoft.Extensions.Caching.Redis code to implement, do not know why before there is this class library, and now NuGet stop, in order not to affect the future upgrade my namespace also use Microsoft.Extensions.Caching.Redis

You can see that Microsoft has four classes here, in fact, we only need three, the fourth one to get it will be wrong:

Using System;
Using System.Threading.Tasks;
Using Microsoft.Extensions.Caching.Distributed;
Using Microsoft.Extensions.Options;

Using Stackexchange.redis;
        Namespace Microsoft.Extensions.Caching.Redis {public class Rediscache:idistributedcache, IDisposable { KEYS[1] = = key//argv[1] = absolute-expiration-ticks as Long ( -1 for none)//argv[2] = Sliding-exp Iration-ticks as Long ( -1 for none)//argv[3] = relative-expiration (long, in seconds,-1 for none)-Min (Absol Ute-expiration-now, Sliding-expiration)//argv[4] = data-byte[]//This order should don't change LUA s Cript depends on it private const string setscript = (@ "Redis.call" (' Hmset ', keys[1], ' absexp ', AR Gv[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) {if (optionsaccessor = = null)
            {throw new ArgumentNullException (Nameof (optionsaccessor));

            } _options = Optionsaccessor.value;
            This allows partitioning a single backend cache-for-use with multiple apps/services. _instance = _options. InstanceName?? String.
        Empty; Byte[] Get (string key) {if (key = = null) {throw new Ar
            Gumentnullexception (nameof (key)); Return GetandrEfresh (key, getdata:true);
                Public Async task<byte[]> Getasync (string key) {if (key = = null) {
            throw new ArgumentNullException (nameof (key));
        Return await Getandrefreshasync (key, getdata:true); public void Set (string key, byte[] value, distributedcacheentryoptions options) {if key =
            = null) {throw new ArgumentNullException (nameof (key));
            } if (value = = null) {throw new ArgumentNullException (nameof (value));
            } if (options = null) {throw new ArgumentNullException (options);

            Connect ();

            var creationtime = Datetimeoffset.utcnow;

            var absoluteexpiration = getabsoluteexpiration (creationtime, Options); var result = _cache. Scriptevaluate (Setscript, new Rediskey[] {_instance + key}, new redisvalue[] {Absoluteexpira tion? Ticks?? Notpresent, Options. SlidingExpiration? Ticks?? Notpresent, Getexpirationinseconds (CreationTime, absoluteexpiration, options)??
        Notpresent, value});
            Public Async Task Setasync (string key, byte[] value, distributedcacheentryoptions options) {
            if (key = = null) {throw new ArgumentNullException (nameof (key));
            } if (value = = null) {throw new ArgumentNullException (nameof (value));
            } if (options = null) {throw new ArgumentNullException (options);

            } await ConnectAsync ();

            var creationtime = Datetimeoffset.utcnow; var absoluteexpiration = GetabSoluteexpiration (creationtime, Options); Await _cache.
                        Scriptevaluateasync (Setscript, new rediskey[] {_instance + key}, new redisvalue[] { Absoluteexpiration? Ticks?? Notpresent, Options. SlidingExpiration? Ticks?? Notpresent, Getexpirationinseconds (CreationTime, absoluteexpiration, options)??
        Notpresent, value}); public void Refresh (string key) {if (key = = null) {throw new
            ArgumentNullException (nameof (key));
        } getandrefresh (key, Getdata:false);
                Public Async Task Refreshasync (string key) {if (key = = null) {
            throw new ArgumentNullException (nameof (key));
        } await Getandrefreshasync (key, Getdata:false);
 private void Connect ()       {if (_connection = null) {_connection = Connectionmultiplexer.connect (_o Ptions.
                Configuration); _cache = _connection.
            Getdatabase ();
                } Private Async Task ConnectAsync () {if (_connection = null) { _connection = await Connectionmultiplexer.connectasync (_options.
                Configuration); _cache = _connection.
            Getdatabase ();
            } private byte[] Getandrefresh (string key, bool GetData) {if (key = null)
            {throw new ArgumentNullException (nameof (key));

            Connect ();
            This also resets the LRU status as desired. Todo:can This is done by one operation on the server side?
            Probably, the trick would just be the DateTimeOffset math.
            Redisvalue[] results; if (getData) {resUlts = _cache.
            Hashmemberget (_instance + key, Absoluteexpirationkey, Slidingexpirationkey, DataKey); else {results = _cache.
            Hashmemberget (_instance + key, Absoluteexpirationkey, Slidingexpirationkey); }//Todo:error handling if (results.
                Length >= 2) {//Always get back two results, even if they all null.
                These operations would no-op in the null scenario. DateTimeOffset?
                absexpr; TimeSpan?
                sldexpr;
                Mapmetadata (results, out of absexpr, out sldexpr);
            Refresh (Key, absexpr, sldexpr); } if (results. Length >= 3 && results[
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.