Условное включение таблиц стилей в макет в зависимости от имени контроллера

#asp.net-mvc

#asp.net-mvc

Вопрос:

Я изучаю ASP.NET Фреймворк MVC 3. На моей странице макета ( _Layout.cshtml ) я хотел бы условно включить некоторые таблицы стилей CSS в зависимости от имени контроллера. Как мне это сделать?

Комментарии:

1. Не делайте этого… Если у вас есть один css-файл для всего вашего веб-сайта в статическом домене с высоким уровнем кэширования, ваш браузер будет делать меньше запросов и уже будет иметь код, необходимый для любой страницы. Посмотрите на исходный код SO, это один css файл. (также один js для веб-сайта)

Ответ №1:

Вы могли бы получить текущее имя контроллера, используя следующее свойство:

 ViewContext.RouteData.GetRequiredString("controller")
  

Таким образом, на основе его значения вы можете включать или не включать таблицу стилей:

 @if (ViewContext.RouteData.GetRequiredString("controller") == "somecontrollername")
{
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
}
  

Или используйте пользовательский помощник:

 public static class CssExtensions
{
    public static IHtmlString MyCss(this HtmlHelper html)
    {
        var currentController = html.ViewContext.RouteData.GetRequiredString("controller");
        if (currentController != "somecontrollername")
        {
            return MvcHtmlString.Empty;
        }

        var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
        var link = new TagBuilder("link");
        link.Attributes["rel"] = "stylesheet";
        link.Attributes["type"] = "text/css";
        link.Attributes["href"] = urlHelper.Content("~/Content/Site.css");
        return MvcHtmlString.Create(link.ToString(TagRenderMode.SelfClosing));
    }
}
  

и в макете просто:

 @Html.MyCss()
  

Ответ №2:

Я бы использовал другой подход. Вместо этого определите базовый контроллер и определите метод setStyleSheet, подобный:

 public abstract class BaseController : Controller
{
    protected override void Intialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);
        SetStyleSheet();
    }

    protected virtual void SetStyleSheet()
    { }
}
  

В производных классах вы можете переопределить, SetStyleSheet чтобы установить что-то вроде ViewData["styleSheet"] и использовать это, например, на вашей главной странице (_Layout.cshtml).

Ответ №3:

Дарин определенно ответил на ваши вопросы, но альтернативой могло бы быть использование имени контроллера в качестве идентификатора некоторого HTML-элемента на вашей странице, что дало бы вам гибкость настройки представлений на уровне контроллера, но сохранило бы ваш CSS в одном файле.

 <body id="<%=ViewContext.RouteData.GetRequiredString("controller").ToLower() %>">
    ... content here
</body>
  

Ответ №4:

Я создал другой метод расширения для ControllerContext, потому что viewContext является его производным, и вы можете вызвать свой метод напрямую.

Например :

 public static class ControllerContextExtensions
{
    public static string GetControllerName(this ControllerContext helper)
    {
        if (helper.Controller == null)
        {
            return string.Empty;
        }

        string[] fullControllerNames = helper.Controller.ToString().Split('.');

        return fullControllerNames[fullControllerNames.Length-1].Replace("Controller",string.Empty);
    }

}
  

И использовать это в вашем _Layout :

 @if(ViewContext.GetControllerName() == "MyControllerName")
{
  //load my css here
}
  

Вы также могли бы передать имя вашего контроллера в качестве параметра и заставить этот метод расширения возвращать bool.