如何在 ASP.Net MVC4 中动态更改主题和_布局

发布于 2025-01-06 01:24:53 字数 615 浏览 6 评论 0原文

我希望能够根据数据库中的设置更改 _Layout.cshtml 视图。
我知道这可能是在 _ViewStart.cshml 视图中完成的。

我正在使用 EF 4.2,并且希望采用不会破坏任何设计模式的解决方案。

不确定如何在 MVC 中执行此操作。

在 Web 表单中,我可以轻松地在母版页的代码隐藏中执行此操作。

我在我的基本控制器中做了类似的事情:

public abstract class BaseController : Controller
{
    private IUserRepository _userRepository;


    protected BaseController()
        : this(
            new UserRepository())
    {
    }


    public BaseController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

我也查看了 FunnelWeb 源代码,但我不太明白他们是如何注入东西的。

I want to be able to change the _Layout.cshtml view based on a setting in my database.
I understand that it is probably done in the _ViewStart.cshml view.

I am using EF 4.2 and want to adapt a solution that will not break any design pattern.

Not sure how to go about doing this in MVC.

In web forms, I could easily do this in the code-behind for the masterpage.

I am doing something like this in my base controller:

public abstract class BaseController : Controller
{
    private IUserRepository _userRepository;


    protected BaseController()
        : this(
            new UserRepository())
    {
    }


    public BaseController(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

I have looked at FunnelWeb source as well but I am not quite getting how they are injecting things..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℡寂寞咖啡 2025-01-13 01:24:53

将此代码添加到 BundleConfig 类的 RegisterBundles 方法中。请注意,我为每个 css 创建一个单独的包,这样我就不会将每个 css 呈现给客户端。我可以在共享 _Layout.cshtml 视图的 HEAD 部分中选择要渲染的包。

bundles.Add(new StyleBundle("~/Content/Ceruleancss").Include(
    "~/Content/bootstrapCerulean.min.css",
        "~/Content/site.css"));

bundles.Add(new StyleBundle("~/Content/defaultcss").Include(
              "~/Content/bootstrap.min.css",
              "~/Content/site.css"));

然后将一些逻辑放入shared_Layout.cshtml中以呈现适当的包。由于此布局视图会针对每个页面触发,因此这是放置它的好地方。

我认为如果您的应用程序支持多个团队,这种方法可以用于品牌推广。我想它也可以用来为用户提供自定义样式。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Contoso University</title>

@{

    if (HttpContext.Current.User.Identity.Name == "MARK")
    {
        @Styles.Render("~/Content/defaultcss");
    }
    else
    {
        @Styles.Render("~/Content/Ceruleancss");
    }

}

Add this code to in the RegisterBundles method of the BundleConfig class. Note that I am creating a separate bundle for each css so that I don't render each css to the client. I can pick which bundle I want to render in the HEAD section of the shared _Layout.cshtml view.

bundles.Add(new StyleBundle("~/Content/Ceruleancss").Include(
    "~/Content/bootstrapCerulean.min.css",
        "~/Content/site.css"));

bundles.Add(new StyleBundle("~/Content/defaultcss").Include(
              "~/Content/bootstrap.min.css",
              "~/Content/site.css"));

Then put some logic in the shared_Layout.cshtml to render the appropriate bundle. Since this layout view fires for every page, this is a good place to put it.

I think this approach could be used for branding if you support multiple corps for your app. It could also be used to provide a custom style by user I suppose.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - Contoso University</title>

@{

    if (HttpContext.Current.User.Identity.Name == "MARK")
    {
        @Styles.Render("~/Content/defaultcss");
    }
    else
    {
        @Styles.Render("~/Content/Ceruleancss");
    }

}
醉城メ夜风 2025-01-13 01:24:53

老问题,但对于遇到这个问题的任何人来说,这里是一个使用操作过滤器属性的很好的解决方案

public class LoadUserLayoutAttribute : ActionFilterAttribute
{
    private readonly string _layoutName;
    public LoadUserLayoutAttribute()
    {
        _layoutName = MethodToGetLayoutNameFromDB();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _layoutName; 
        }
    }
}

,然后,您可以使用此自定义属性向基本控制器(或操作)添加一个属性:

    [LoadUserLayout]
    public abstract class BaseController : Controller
    {
       ...
    }

Old Question but for anyone coming across this question here is a nice solution using Action Filters Attributes

public class LoadUserLayoutAttribute : ActionFilterAttribute
{
    private readonly string _layoutName;
    public LoadUserLayoutAttribute()
    {
        _layoutName = MethodToGetLayoutNameFromDB();
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _layoutName; 
        }
    }
}

and then, you can add an attribute to your base controller (or action) with this custom attribute:

    [LoadUserLayout]
    public abstract class BaseController : Controller
    {
       ...
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文