Есть ли в .Net Core MVC 2.1 эквивалент запуска сессии? - PullRequest
0 голосов
/ 27 сентября 2018

В MVC 5 вы можете присвоить значение сеансу в global.asx, когда сеанс начался.Есть ли способ сделать это в .Net Core MVC?У меня настроен сеанс, но в промежуточном программном обеспечении он вызывается при каждом запросе.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Решение nercan будет работать, но я думаю, что я нашел решение, которое требует меньше кода и может иметь другие преимущества.

Сначала оберните DistributedSessionStore следующим образом:

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Session;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;

public interface IStartSession
{
    void StartSession(ISession session);
}

public class DistributedSessionStoreWithStart : ISessionStore
{
    DistributedSessionStore innerStore;
    IStartSession startSession;
    public DistributedSessionStoreWithStart(IDistributedCache cache, 
        ILoggerFactory loggerFactory, IStartSession startSession)
    {
        innerStore = new DistributedSessionStore(cache, loggerFactory);
        this.startSession = startSession;
    }

    public ISession Create(string sessionKey, TimeSpan idleTimeout, 
        TimeSpan ioTimeout, Func<bool> tryEstablishSession, 
        bool isNewSessionKey)
    {
        ISession session = innerStore.Create(sessionKey, idleTimeout, ioTimeout,
             tryEstablishSession, isNewSessionKey);
        if (isNewSessionKey)
        {
            startSession.StartSession(session);
        }
        return session;
    }
}

Затем зарегистрируйте этоновый класс в Startup.cs:

class InitSession : IStartSession
{
    public void StartSession(ISession session)
    {
        session.SetString("Hello", "World");
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSingleton<IStartSession, InitSession>();
        services.AddSingleton<ISessionStore, DistributedSessionStoreWithStart>();
        services.AddSession();
        ...
    }

Полный код здесь: https://github.com/SurferJeffAtGoogle/scratch/tree/master/StartSession/MVC

0 голосов
/ 27 сентября 2018

Я использую это в живом проекте.Работает правильно.если вы хотите сохранить его, когда приложение останавливается.Вы должны использовать DistributedCache.Например, я использую DistributedRedisCache.

Добавить для запуска этот код;

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromMinutes(60);
            options.Cookie.HttpOnly = true;
        });
// for redis distributed cache

//services.AddDistributedRedisCache(options =>
            //    {
                 //   options.InstanceName = $"{Configuration["DistributedRedisCacheInstance"]}";
                 //   options.Configuration = $"{Configuration["DistributedRedisCacheHost"]}";
              //  });
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor acc)
    {
        app.UseSession();

    }

И добавить новое расширение сеанса;

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System.Text;

namespace SampleApp
{
    public static class SessionExtensions
    {
        public static void SetObjectAsJson<T>(this ISession session, string key, T value)
        {
            session.Set(key, Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(value)));
        }

        public static T GetObjectFromJson<T>(this ISession session, string key)
        {
            session.TryGetValue(key, out byte[] dataByte);
            string data = dataByte != null ? Encoding.UTF8.GetString(dataByte) : null;

            return data == null ? default(T) : JsonConvert.DeserializeObject<T>(data);
        }
    }
}

И использовать get или setто же самое;

var sessionItem = httpContext.Session.GetObjectFromJson<string>("sessionItem");
//or


ContextProviderExtension.HttpContextAccessor.HttpContext.Session.SetObjectAsJson("sessionItem", sessionItem);

вам нужно это расширение;

using Microsoft.AspNetCore.Http;
using System;

namespace SampleApp
{
    public static class ContextProviderExtension
    {
        static IHttpContextAccessor httpContextAccessor = null;
        public static IHttpContextAccessor HttpContextAccessor
        {
            get { return httpContextAccessor; }
            set
            {
                if (httpContextAccessor != null)
                {
                    throw new Exception("");
                }
                httpContextAccessor = value;
            }
        }
    }
}

Полагаю, оно будет работать.

 using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;


namespace SampleApp
{
    public class SessionMiddleware
    {
        private readonly RequestDelegate _next;

        public SessionMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            var sessionItem = httpContext.Session.GetObjectFromJson<string>("test");
            if (sessionItem == null)
                httpContext.Session.SetObjectAsJson<string>("test", httpContext.Session.Id);//httpContext.Session.Id or set a value
            await _next.Invoke(httpContext);
        }
    }

    public static class SessionMiddlewareExtensions
    {
        public static IApplicationBuilder UseSessionMiddleware(this IApplicationBuilder app)
        {
            return app.UseMiddleware<SessionMiddleware>();
        }
    }
}

и добавьте startup.cs Настройте метод после приложения.UseSession ();

app.UseSessionMiddleware();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...