【问题标题】:ASP.NET Core 2.1 insert CSS in layout based on data in DBASP.NET Core 2.1 根据 DB 中的数据在布局中插入 CSS
【发布时间】:2018-06-15 14:32:51
【问题描述】:

我遇到了一个我正在努力解决的问题。一些背景知识:用户可以在我的应用程序中选择应用程序使用的配色方案,这个选择存储在数据库中。

我想要做的是基于这个选择,在页面加载时,为用户所做的选择提供 CSS 文件。

我一直在尝试做的是通过在 _Layout.cshtml 页面中执行 AJAX 请求来检查用户的选择,并将适当的 CSS 附加到标题中。这是有效的,但不是很好,因为有一些延迟,而且它不是一个好的解决方案,因为有时元素的某些样式在 CSS 加载后不正确。

我想做的是在服务器端做这个检查,就像控制器中的普通视图一样(你知道布局页面缺少控制器,所以这就是我卡住的地方)。然后在 _Layout 视图中添加正确的 CSS。

亲爱的堆栈溢出者,你对我有什么建议可以实现吗?我的用户需要那种甜蜜甜蜜的黑暗主题。 ;)

提前致谢!

【问题讨论】:

  • 是的,对于连接到控制器的普通视图,我会这样做,但由于布局视图缺少控制器,我不确定这是否可行?
  • 在这方面就像 MVC5 AFAIK。布局的“控制器”实际上是使用该布局的视图的控制器操作。
  • 但这是 .net CORE !这意味着您实际上可以在您的视图中注入模型......并且在您的_Layout 中。这可能是使用此功能的正确时机。您还可以使用 html 标签助手或组件来获得更简洁的语法,而不是使用这些肮脏的if 我建议...(netcore 2 很棒,立即使用它!)
  • 非常感谢 Wndrr,您和 C# discord 频道的用户都提出了这个建议,所以我实现了它,它运行良好。由于克里斯蒂安在下面写了一个答案来解释我是如何做到的,因此我会将他的帖子标记为已接受的答案,但是你们都向我发送了正确的方向,对此我表示感谢! :)

标签: css asp.net-core


【解决方案1】:

创建服务

public class ThemeService
{
    private readonly MyDbContext  _dbContext;
    private readonly IMemoryCache _memoryCache;

    public ThemeService(MyDbContext dbContext, IMemoryCache memoryCache)
    {
        //Here you can also inject the UserManager<T> if needed
        _dbContext = dbContext;
        _memoryCache = memoryCache;
    }

    public string GetTheme()
    {
        throw new NotImplementedException();
    }
}

并将其注册到服务容器scoped(因为你需要DbContext):

services.AddScoped<ThemeService, ThemeService>();

在你看来,只需注入它

@inject ThemeService ThemeService;

然后在视图中:

<link type="text/css" href="@ThemeService.GetTheme()" />

【讨论】:

  • 我刚回来写一篇关于我如何解决它的帖子,但不再需要了,你为我写的哈哈。用户“shadow_kras”在 Discord C# 频道和@Wndrr 在 SO 上向这个方向发送。非常感谢,这正是我一直在寻找的,我现在可以对我想要添加到布局视图中的其他一些东西做同样的事情。优秀的答案! :)
  • @christian Gollhardt 感谢您的回答,它对我帮助很大,我想知道当我添加时我的服务是否是异步的,我从现在工作的布局中调用它。关于我如何解决这个问题的任何想法。再次感谢
  • await他们@wandos 吗?
  • @ChristianGollhardt 我试过但没用,@{await ThemeService.GetTheme(); } 没用
  • 我这里没有IDE,但语法不正确@await ThemeService.GetThemeAsync()@wandos
【解决方案2】:

如果您只是有一个“暗”和“亮”主题,为什么不在存储用户选择的数据库中存储一个布尔值,然后在视图的_Layout 中执行类似的操作

@if(ViewBag.IsLightTheme)
{
    <link rel="stylesheet"  type="text/css" href="path.to.light.theme" />
}

else
{
    <link rel="stylesheet"  type="text/css" href="path.to.dark.theme" />
}

在您的控制器的构造函数中,您需要将来自数据库的值分配给您的ViewBag.IsLightTheme var(您可能希望在那里使用某种形式的缓存,因为这将在每个页面上调用)。

如果您不只是有两个主题,您可以使用更精细的方式来选择基于switch 或类似的东西来编写哪个href

另一种选择是始终为您的 CSS 使用相同的 URL,这实际上指向您的一个控制器的操作,该控制器将执行对数据库的调用并根据使用 return Content() 的答案返回不同的 CSS .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    相关资源
    最近更新 更多