首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在_Layout中访问会话而不必担心它已过期

如何在_Layout中访问会话而不必担心它已过期
EN

Stack Overflow用户
提问于 2016-02-22 18:26:14
回答 2查看 361关注 0票数 1

我正在使用ASP.NET核心和标识3。

当我登录时,我读取当前select用户界面模板,并在我的_Layout.cshml文件中基于该模板加载css

用户可以更改他的主题,我通过控制器将其存储在会话变量中。

代码语言:javascript
代码运行次数:0
运行
复制
public IActionResult ChangeTheme(int id, string returnUrl)
{
    HttpContext.Session.SetInt32("Template", (id));
    return Redirect(returnUrl);
}

与每次加载cshtml查询数据库不同,我将模板放在会话变量中,在Layout.cshtml中根据模板呈现不同的css。

代码语言:javascript
代码运行次数:0
运行
复制
        switch (template)
        {
            case (int)TemplateEnum.Template2:
                <text>
                <link rel="stylesheet" href="~/css/template1.css" />
                </text>
                break;
            case (int)TemplateEnum.Template2:
                <text>
                <link rel="stylesheet" href="~/css/template2.css" />
                </text>
                break;
        {

我想知道如果会议结束了会发生什么。

  1. 考虑到这一点,我访问我的_Layout.cshtml中的值,如果它变为null,并且在呈现新页面之前立即从db加载它,那么它就在那里了。
  2. 既然我使用了标识3,那么声明可能是一个更好的选择吗?我以前没用过。我上面的例子的代码是什么?
  3. 另一个更适合我的方案?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-22 21:35:19

我没有每次加载cshtml来查询数据库,而是将模板放在会话变量中,并在Layout.cshtml中根据模板呈现不同的css。

如果访问数据库是您唯一关心的问题,并且您已经抽象了您的存储库(或者用户存储库,如果您将它存储在标识类型上),那么您可以使用装饰器模式来实现本地缓存。

代码语言:javascript
代码运行次数:0
运行
复制
public interface IUserRepository
{
    string GetUserTheme(int userId);
    void SetUserTheme(int userId, string theme);
}

public class CachedUserRepository : IUserRepository
{
    private readonly IMemoryCache cache;
    private readonly IUserRepository userRepository;
    // Cache Expire duration
    private static TimeSpan CacheDuration = TimeSpan.FromMinutes(5);

    public CachedUserRepository(IUserRepository userRepository, IMemoryCache memoryCache)
    {
        if (userRepository == null)
            throw new ArgumentNullException(nameof(userRepository));

        if (memoryCache == null)
            throw new ArgumentNullException(nameof(memoryCache));

        this.userRepository = userRepository;
        this.cache = memoryCache;
    }

    public string GetUserTheme(int userId)
    {
        string theme;

        // adding a prefix to make the key unique
        if (cache.TryGetValue($"usertheme-{userId}", out theme))
        {
            // found in cache
            return theme;
        };

        // fetch from database
        theme = userRepository.GetUserTheme(userId);

        // put it into the cache, expires in 5 minutes
        cache.Set($"usertheme-{userId}", theme, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = CacheDuration });

        return theme;
    }

    public void SetUserTheme(int userId, string theme)
    {
        // persist it
        userRepository.SetUserTheme(userId, theme);


        // put it into the cache, expires in 5 minutes
        cache.Set($"usertheme-{userId}", theme, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = CacheDuration });
    }
}

问题是,在默认的ASP.NET核心DI系统中,不存在对装饰器的内置支持。您必须使用第三方IoC容器(Autofac、StructureMap等)。

你当然可以这样注册

代码语言:javascript
代码运行次数:0
运行
复制
    services.AddScoped<IUserRepository>(container => {
        return new CachedUserRepository(container.GetService<UserRepository>(), container.GetServices<IMemoryCache>());
    });

但这有点麻烦。否则,将其存储在一个长期存在的cookie中,它的优点是,当用户未登录时,主题仍然处于活动状态,并且您可以在用户登录时设置cookie。

票数 1
EN

Stack Overflow用户

发布于 2016-02-22 20:06:26

如果您愿意,当然可以将主题存储在用户的标识中,但是无论何时更新主题,您都必须辞职。

你会做这样的事情:

代码语言:javascript
代码运行次数:0
运行
复制
userManager.AddClaimAsync(user, new Claim("Template", id+""));
signInManager.SignInAsync(user);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35561070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档