Adicione arquivos CSS ou JavaScript ao cabeçalho do layout a partir de visualizações ou visualizações parciais

176

Cabeçalho das páginas de layout:

<head>
    <link href="@Url.Content("~/Content/themes/base/Site.css")"
          rel="stylesheet" type="text/css" />
</head>

Uma Visualização (AnotherView) do aplicativo precisa:

<link href="@Url.Content("~/Content/themes/base/AnotherPage.css")"
      rel="stylesheet" type="text/css" />

e AnotherView tem uma vista parcial (AnotherPartial) que precisa de:

<link href="@Url.Content("~/Content/themes/base/AnotherPartial.css")"
      rel="stylesheet" type="text/css" />

Pergunta: Como podemos adicionar esses links de arquivos CSS para os links AnotherView e AnotherPartial no cabeçalho Layout ?

RenderSection não é uma boa ideia, porque o AnotherPage pode ter mais de um Partials. Adicionar todo o CSS ao cabeçalho não é útil porque ele muda dinamicamente (depende de outras páginas).

Nuri YILMAZ
fonte
@NuriYILMAZ, é uma enorme diferença entre "de visualizações" e "ou visualizações parciais", como diz o seu título. De qualquer forma, novas idéias sobre esse assunto?
Shimmy Weitzhandler

Respostas:

196

Layout:

<html>
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title</title>
        <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
        <script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")" type="text/javascript"></script>
        @if (IsSectionDefined("AddToHead"))
        {
            @RenderSection("AddToHead", required: false)
        }

        @RenderSection("AddToHeadAnotherWay", required: false)
    </head>

Visão:

@model ProjectsExt.Models.DirectoryObject

@section AddToHead{
    <link href="@Url.Content("~/Content/Upload.css")" rel="stylesheet" type="text/css" />
}
RouR
fonte
5
Eu acho que essa é a solução mais simples.
Iamichi
Solução agradável e pronta para uso!
Jerrylroberts
14
Isso não funcionará se a AddToHeadseção estiver em uma exibição parcial incorporada no View.
Shimmy Weitzhandler
57
A pergunta mencionou especificamente a vista parcial e esta resposta com a classificação mais alta não resolve o problema! Esta pode ser uma excelente solução para outra consulta, mas não esta.
corvo vulcan
1
Teria sido uma solução elegante se funcionasse com vistas parciais.
21919 Jonny
75

Atualização : exemplo básico disponível em https://github.com/speier/mvcassetshelper

Estamos usando a seguinte implementação para adicionar arquivos JS e CSS à página de layout.

Vista ou Vista Parcial:

@{
    Html.Assets().Styles.Add("/Dashboard/Content/Dashboard.css");
    Html.Assets().Scripts.Add("/Dashboard/Scripts/Dashboard.js");
}

Página de layout:

<head>
    @Html.Assets().Styles.Render()
</head>

<body>
    ...
    @Html.Assets().Scripts.Render()
</body>

Extensão HtmlHelper:

public static class HtmlHelperExtensions
{
    public static AssetsHelper Assets(this HtmlHelper htmlHelper)
    {
        return AssetsHelper.GetInstance(htmlHelper);
    }    
}

public class AssetsHelper 
{
    public static AssetsHelper GetInstance(HtmlHelper htmlHelper)
    {
        var instanceKey = "AssetsHelperInstance";

        var context = htmlHelper.ViewContext.HttpContext;
        if (context == null) return null;

        var assetsHelper = (AssetsHelper)context.Items[instanceKey];

        if (assetsHelper == null)
            context.Items.Add(instanceKey, assetsHelper = new AssetsHelper());

        return assetsHelper;
    }

    public ItemRegistrar Styles { get; private set; }
    public ItemRegistrar Scripts { get; private set; }

    public AssetsHelper()
    {
        Styles = new ItemRegistrar(ItemRegistrarFormatters.StyleFormat);
        Scripts = new ItemRegistrar(ItemRegistrarFormatters.ScriptFormat);
    }
}

public class ItemRegistrar
{
    private readonly string _format;
    private readonly IList<string> _items;

    public ItemRegistrar(string format)
    {
        _format = format;
        _items = new List<string>();
    }

    public ItemRegistrar Add(string url)
    {
        if (!_items.Contains(url))
            _items.Add(url);

        return this;
    }

    public IHtmlString Render()
    {
        var sb = new StringBuilder();

        foreach (var item in _items)
        {
            var fmt = string.Format(_format, item);
            sb.AppendLine(fmt);
        }

        return new HtmlString(sb.ToString());
    }
}

public class ItemRegistrarFormatters
{
    public const string StyleFormat = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
    public const string ScriptFormat = "<script src=\"{0}\" type=\"text/javascript\"></script>";
}
Kalman Speier
fonte
2
@JBeckton: Dê uma olhada no código e substituir Insertmétodos com os Addmétodos
Valamas
9
@ Kalman - a segurança de threads disso (na minha opinião) foi bastante questionada: stackoverflow.com/questions/6609586/…
Marc Gravell
2
Isto está muito errado; deve ser [ThreadStatic], ou, de preferência, armazenado em HttpContext.Items.
SLaks
6
Estou esquecendo de algo? Se Styles.Render () for chamado em <head>, todos os arquivos css adicionados após <head> (ou seja, arquivos adicionados em visualizações parciais) não serão renderizados. (MVC torna a partir de cima para baixo.)
ken
3
@FernandoCorreia Eu acho que você entendeu tudo errado. As seções nomeadas não funcionam em vistas parciais, que é a base de todo esse segmento.
Shimmy Weitzhandler
11

Infelizmente, isso não é possível por padrão para usar sectioncomo outro usuário sugeriu, uma vez que a sectionestá disponível apenas para o imediato childde a View.

No entanto, o que funciona é implementar e redefinir o sectionem todas as visualizações , o que significa:

section Head
{
    @RenderSection("Head", false)
}

Dessa forma, toda visualização pode implementar uma seção principal, não apenas os filhos imediatos. Porém, isso funciona apenas parcialmente, especialmente com várias parciais que os problemas começam (como você mencionou na sua pergunta).

Portanto, a única solução real para o seu problema é usar o ViewBag. O melhor seria provavelmente uma coleção separada (lista) para CSS e scripts. Para que isso funcione, é necessário garantir que o Listusado seja inicializado antes que qualquer uma das visualizações seja executada. Em seguida, você pode fazer coisas assim na parte superior de todas as visualizações / parciais (sem se preocupar se o valor Scriptsou Stylesé nulo:

ViewBag.Scripts.Add("myscript.js");
ViewBag.Styles.Add("mystyle.css");

No layout, você pode percorrer as coleções e adicionar os estilos com base nos valores em List.

@foreach (var script in ViewBag.Scripts)
{
    <script type="text/javascript" src="@script"></script>
}
@foreach (var style in ViewBag.Styles)
{
    <link href="@style" rel="stylesheet" type="text/css" />
}

Eu acho feio, mas é a única coisa que funciona.

****** UPDATE **** Desde que começa a executar as visualizações internas primeiro e a trabalhar para o layout e os estilos CSS estão em cascata, provavelmente faria sentido reverter a lista de estilos por meio de ViewBag.Styles.Reverse().

Dessa forma, o estilo mais externo é adicionado primeiro, o que está alinhado com o funcionamento das folhas de estilo CSS.

ntziolis
fonte
1
Obrigado ntziolis. Parece bom, mas as cabeças de layout de navalha funcionam primeiro antes de outras visualizações, e a dinâmica .scripts e .styles estava vazia antes de outras visualizações. Eu encontrei um bom blog sobre isso e compartilhei essa pergunta.
Nuri YILMAZ
Isso funcionará para qualquer visualização derivada, mas não para parciais. Para parciais, de fato, a ordem de execução está errada. basicamente para parciais, não há como incluí-las no cabeçalho. Eu sugeriria, em vez de adicioná-lo ao cabeçalho, basta adicioná-lo no início da tag body. Não seria minha primeira escolha, mas dessa maneira você tem uma maneira concisa de gerenciar todos os estilos / js em um só lugar, em vez de dispersá-los.
Ntziolis
Eu estou de acordo com você. Porque eu encontrei algumas soluções listadas na resposta, mas são exatamente as soluções js. Estou realmente me perguntando por que não pudemos usar a página de layout como asp.net clássico. Isso significa que posso acessar a página filho.
Nuri YILMAZ 27/02
11

Você pode definir a seção pelo método RenderSection no layout.

Layout

<head>
  <link href="@Url.Content("~/Content/themes/base/Site.css")"
    rel="stylesheet" type="text/css" />
  @RenderSection("heads", required: false)
</head>

Em seguida, você pode incluir seus arquivos css na área de seção da sua exibição, exceto a exibição parcial .

A seção funciona em exibição, mas não funciona em exibição parcial por design .

<!--your code -->
@section heads
{
  <link href="@Url.Content("~/Content/themes/base/AnotherPage.css")"
  rel="stylesheet" type="text/css" />
}

Se você realmente deseja usar a área de seção em vista parcial, siga o artigo para redefinir o método RenderSection.

Navalha, layouts aninhados e seções redefinidas - Marcin no ASP.NET

Milkker
fonte
6

Eu tive um problema semelhante e acabei aplicando a excelente resposta de Kalman com o código abaixo (não tão elegante, mas sem dúvida mais expansível):

namespace MvcHtmlHelpers
{
    //http://stackoverflow.com/questions/5110028/add-css-or-js-files-to-layout-head-from-views-or-partial-views#5148224
    public static partial class HtmlExtensions
    {
        public static AssetsHelper Assets(this HtmlHelper htmlHelper)
        {
            return AssetsHelper.GetInstance(htmlHelper);
        }
    }
    public enum BrowserType { Ie6=1,Ie7=2,Ie8=4,IeLegacy=7,W3cCompliant=8,All=15}
    public class AssetsHelper
    {
        public static AssetsHelper GetInstance(HtmlHelper htmlHelper)
        {
            var instanceKey = "AssetsHelperInstance";
            var context = htmlHelper.ViewContext.HttpContext;
            if (context == null) {return null;}
            var assetsHelper = (AssetsHelper)context.Items[instanceKey];
            if (assetsHelper == null){context.Items.Add(instanceKey, assetsHelper = new AssetsHelper(htmlHelper));}
            return assetsHelper;
        }
        private readonly List<string> _styleRefs = new List<string>();
        public AssetsHelper AddStyle(string stylesheet)
        {
            _styleRefs.Add(stylesheet);
            return this;
        }
        private readonly List<string> _scriptRefs = new List<string>();
        public AssetsHelper AddScript(string scriptfile)
        {
            _scriptRefs.Add(scriptfile);
            return this;
        }
        public IHtmlString RenderStyles()
        {
            ItemRegistrar styles = new ItemRegistrar(ItemRegistrarFormatters.StyleFormat,_urlHelper);
            styles.Add(Libraries.UsedStyles());
            styles.Add(_styleRefs);
            return styles.Render();
        }
        public IHtmlString RenderScripts()
        {
            ItemRegistrar scripts = new ItemRegistrar(ItemRegistrarFormatters.ScriptFormat, _urlHelper);
            scripts.Add(Libraries.UsedScripts());
            scripts.Add(_scriptRefs);
            return scripts.Render();
        }
        public LibraryRegistrar Libraries { get; private set; }
        private UrlHelper _urlHelper;
        public AssetsHelper(HtmlHelper htmlHelper)
        {
            _urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            Libraries = new LibraryRegistrar();
        }
    }
    public class LibraryRegistrar
    {
        public class Component
        {
            internal class HtmlReference
            {
                internal string Url { get; set; }
                internal BrowserType ServeTo { get; set; }
            }
            internal List<HtmlReference> Styles { get; private set; }
            internal List<HtmlReference> Scripts { get; private set; }
            internal List<string> RequiredLibraries { get; private set; }

            public Component()
            {
                Styles = new List<HtmlReference>();
                Scripts = new List<HtmlReference>();
                RequiredLibraries = new List<string>();
            }
            public Component Requires(params string[] libraryNames)
            {
                foreach (var lib in libraryNames)
                {
                    if (!RequiredLibraries.Contains(lib))
                        { RequiredLibraries.Add(lib); }
                }
                return this;
            }
            public Component AddStyle(string url, BrowserType serveTo = BrowserType.All)
            {
                Styles.Add(new HtmlReference { Url = url, ServeTo=serveTo });
                return this;
            }
            public Component AddScript(string url, BrowserType serveTo = BrowserType.All)
            {
                Scripts.Add(new HtmlReference { Url = url, ServeTo = serveTo });
                return this;
            }
        }
        private readonly Dictionary<string, Component> _allLibraries = new Dictionary<string, Component>();
        private List<string> _usedLibraries = new List<string>();
        internal IEnumerable<string> UsedScripts()
        {
            SetOrder();
            var returnVal = new List<string>();
            foreach (var key in _usedLibraries)
            {
                returnVal.AddRange(from s in _allLibraries[key].Scripts
                                   where IncludesCurrentBrowser(s.ServeTo)
                                   select s.Url);
            }
            return returnVal;
        }
        internal IEnumerable<string> UsedStyles()
        {
            SetOrder();
            var returnVal = new List<string>();
            foreach (var key in _usedLibraries)
            {
                returnVal.AddRange(from s in _allLibraries[key].Styles
                                   where IncludesCurrentBrowser(s.ServeTo)
                                   select s.Url);
            }
            return returnVal;
        }
        public void Uses(params string[] libraryNames)
        {
            foreach (var name in libraryNames)
            {
                if (!_usedLibraries.Contains(name)){_usedLibraries.Add(name);}
            }
        }
        public bool IsUsing(string libraryName)
        {
            SetOrder();
            return _usedLibraries.Contains(libraryName);
        }
        private List<string> WalkLibraryTree(List<string> libraryNames)
        {
            var returnList = new List<string>(libraryNames);
            int counter = 0;
            foreach (string libraryName in libraryNames)
            {
                WalkLibraryTree(libraryName, ref returnList, ref counter);
            }
            return returnList;
        }
        private void WalkLibraryTree(string libraryName, ref List<string> libBuild, ref int counter)
        {
            if (counter++ > 1000) { throw new System.Exception("Dependancy library appears to be in infinate loop - please check for circular reference"); }
            Component library;
            if (!_allLibraries.TryGetValue(libraryName, out library))
                { throw new KeyNotFoundException("Cannot find a definition for the required style/script library named: " + libraryName); }
            foreach (var childLibraryName in library.RequiredLibraries)
            {
                int childIndex = libBuild.IndexOf(childLibraryName);
                if (childIndex!=-1)
                {
                    //child already exists, so move parent to position before child if it isn't before already
                    int parentIndex = libBuild.LastIndexOf(libraryName);
                    if (parentIndex>childIndex)
                    {
                        libBuild.RemoveAt(parentIndex);
                        libBuild.Insert(childIndex, libraryName);
                    }
                }
                else
                {
                    libBuild.Add(childLibraryName);
                    WalkLibraryTree(childLibraryName, ref libBuild, ref counter);
                }
            }
            return;
        }
        private bool _dependenciesExpanded;
        private void SetOrder()
        {
            if (_dependenciesExpanded){return;}
            _usedLibraries = WalkLibraryTree(_usedLibraries);
            _usedLibraries.Reverse();
            _dependenciesExpanded = true;
        }
        public Component this[string index]
        {
            get
            {
                if (_allLibraries.ContainsKey(index))
                    { return _allLibraries[index]; }
                var newComponent = new Component();
                _allLibraries.Add(index, newComponent);
                return newComponent;
            }
        }
        private BrowserType _requestingBrowser;
        private BrowserType RequestingBrowser
        {
            get
            {
                if (_requestingBrowser == 0)
                {
                    var browser = HttpContext.Current.Request.Browser.Type;
                    if (browser.Length > 2 && browser.Substring(0, 2) == "IE")
                    {
                        switch (browser[2])
                        {
                            case '6':
                                _requestingBrowser = BrowserType.Ie6;
                                break;
                            case '7':
                                _requestingBrowser = BrowserType.Ie7;
                                break;
                            case '8':
                                _requestingBrowser = BrowserType.Ie8;
                                break;
                            default:
                                _requestingBrowser = BrowserType.W3cCompliant;
                                break;
                        }
                    }
                    else
                    {
                        _requestingBrowser = BrowserType.W3cCompliant;
                    }
                }
                return _requestingBrowser;
            }
        }
        private bool IncludesCurrentBrowser(BrowserType browserType)
        {
            if (browserType == BrowserType.All) { return true; }
            return (browserType & RequestingBrowser) != 0;
        }
    }
    public class ItemRegistrar
    {
        private readonly string _format;
        private readonly List<string> _items;
        private readonly UrlHelper _urlHelper;

        public ItemRegistrar(string format, UrlHelper urlHelper)
        {
            _format = format;
            _items = new List<string>();
            _urlHelper = urlHelper;
        }
        internal void Add(IEnumerable<string> urls)
        {
            foreach (string url in urls)
            {
                Add(url);
            }
        }
        public ItemRegistrar Add(string url)
        {
            url = _urlHelper.Content(url);
            if (!_items.Contains(url))
                { _items.Add( url); }
            return this;
        }
        public IHtmlString Render()
        {
            var sb = new StringBuilder();
            foreach (var item in _items)
            {
                var fmt = string.Format(_format, item);
                sb.AppendLine(fmt);
            }
            return new HtmlString(sb.ToString());
        }
    }
    public class ItemRegistrarFormatters
    {
        public const string StyleFormat = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
        public const string ScriptFormat = "<script src=\"{0}\" type=\"text/javascript\"></script>";
    }
}

O projeto contém um método estático AssignAllResources:

assets.Libraries["jQuery"]
        .AddScript("~/Scripts/jquery-1.10.0.min.js", BrowserType.IeLegacy)
        .AddScript("~/Scripts//jquery-2.0.1.min.js",BrowserType.W3cCompliant);
        /* NOT HOSTED YET - CHECK SOON 
        .AddScript("//ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js",BrowserType.W3cCompliant);
        */
    assets.Libraries["jQueryUI"].Requires("jQuery")
        .AddScript("//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js",BrowserType.Ie6)
        .AddStyle("//ajax.aspnetcdn.com/ajax/jquery.ui/1.9.2/themes/eggplant/jquery-ui.css",BrowserType.Ie6)
        .AddScript("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js", ~BrowserType.Ie6)
        .AddStyle("//ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/eggplant/jquery-ui.css", ~BrowserType.Ie6);
    assets.Libraries["TimePicker"].Requires("jQueryUI")
        .AddScript("~/Scripts/jquery-ui-sliderAccess.min.js")
        .AddScript("~/Scripts/jquery-ui-timepicker-addon-1.3.min.js")
        .AddStyle("~/Content/jQueryUI/jquery-ui-timepicker-addon.css");
    assets.Libraries["Validation"].Requires("jQuery")
        .AddScript("//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js")
        .AddScript("~/Scripts/jquery.validate.unobtrusive.min.js")
        .AddScript("~/Scripts/mvcfoolproof.unobtrusive.min.js")
        .AddScript("~/Scripts/CustomClientValidation-1.0.0.min.js");
    assets.Libraries["MyUtilityScripts"].Requires("jQuery")
        .AddScript("~/Scripts/GeneralOnLoad-1.0.0.min.js");
    assets.Libraries["FormTools"].Requires("Validation", "MyUtilityScripts");
    assets.Libraries["AjaxFormTools"].Requires("FormTools", "jQueryUI")
        .AddScript("~/Scripts/jquery.unobtrusive-ajax.min.js");
    assets.Libraries["DataTables"].Requires("MyUtilityScripts")
        .AddScript("//ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js")
        .AddStyle("//ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css")
        .AddStyle("//ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables_themeroller.css");
    assets.Libraries["MvcDataTables"].Requires("DataTables", "jQueryUI")
        .AddScript("~/Scripts/jquery.dataTables.columnFilter.min.js");
    assets.Libraries["DummyData"].Requires("MyUtilityScripts")
        .AddScript("~/Scripts/DummyData.js")
        .AddStyle("~/Content/DummyData.css");     

na página _layout

@{
    var assets = Html.Assets();
    CurrentResources.AssignAllResources(assets);
    Html.Assets().RenderStyles()
}
</head>
...
    @Html.Assets().RenderScripts()
</body>

e nas parciais e visualizações

Html.Assets().Libraries.Uses("DataTables");
Html.Assets().AddScript("~/Scripts/emailGridUtilities.js");
Brent
fonte
Interessante. Parece exagero, mas vejo isso sendo usado mais em sites que não têm escolha, mas para lidar com usuários que usam versões mais antigas do ie ... como em ambientes corporativos em que alguns países não foram atualizados e você quer se matar. ri muito. +1 para isso
pqsk
5

Eu tentei resolver esse problema.

Minha resposta está aqui.

"DynamicHeader" - http://dynamicheader.codeplex.com/ , https://nuget.org/packages/DynamicHeader

Por exemplo, _Layout.cshtml é:

<head>
@Html.DynamicHeader()
</head>
...

E você pode registrar arquivos .js e .css no "DynamicHeader" qualquer lugar que desejar.

Por exemplo, o bloco de código em AnotherPartial.cshtm é:

@{
  DynamicHeader.AddSyleSheet("~/Content/themes/base/AnotherPartial.css");
  DynamicHeader.AddScript("~/some/myscript.js");
}

Então, finalmente, o HTML de saída é:

<html>
  <link href="/myapp/Content/themes/base/AnotherPartial.css" .../>
  <script src="/myapp/some/myscript.js" ...></script>
</html>
...
jsakamoto
fonte
4

Experimente a solução pronta para uso (ASP.NET MVC 4 ou posterior):

@{
    var bundle = BundleTable.Bundles.GetRegisteredBundles().First(b => b.Path == "~/js");

    bundle.Include("~/Scripts/myFile.js");
}
RouR
fonte
Estou recebendo um erro:CS0103: The name 'BundleTable' does not exist in the current context
Kunal
NVV: resolvido. Tinha que acrescentar System.Web.OptimizationieSystem.Web.Optimization.BundleTable.Bundles.GetRegisteredBundles().First(b => b.Path == "~/bundles/css");
Kunal
1
Isso não modifica o pacote globalmente? Se você fizer isso na página A e a página mais tarde aberta B, página B também terá myFile.js incluído o que eu não acho que foi procurado pelo OP
miles82
4

Para aqueles que usam o ASP.NET MVC 4 - isso pode ser útil.

Primeiro, adicionei uma classe BundleConfig na pasta App_Start.

Aqui está o meu código que eu usei para criá-lo:

using System.Web.Optimization;

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/SiteMaster.css"));
    }
}

Segundo, registrei a classe BundleConfig no arquivo Global.asax:

protected void Application_Start()
{
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Terceiro, adicionei ajudantes de estilo ao meu arquivo CSS:

/* Styles for validation helpers */
.field-validation-error {
    color: red;
    font-weight: bold;
}

.field-validation-valid {
    display: none;
}

input.input-validation-error {
    border: 1px solid #e80c4d;
}

input[type="checkbox"].input-validation-error {
    border: 0 none;
}

.validation-summary-errors {
    color: #e80c4d;
    font-weight: bold;
    font-size: 1.1em;
}

.validation-summary-valid {
    display: none;
}

Por fim, usei essa sintaxe em qualquer modo de exibição:

@Styles.Render("~/Content/css")
Terry H
fonte
3

Aqui está um plugin do NuGet chamado Cassette , que, entre outras coisas, fornece a capacidade de referenciar scripts e estilos em parciais.

Embora haja várias configurações disponíveis para este plugin, o que o torna altamente flexível. Aqui está a maneira mais simples de consultar arquivos de script ou de folha de estilo:

Bundles.Reference("scripts/app");

De acordo com a documentação :

As chamadas para Referencepodem aparecer em qualquer lugar da página, layout ou exibição parcial.

O argumento do caminho pode ser um dos seguintes:

  • Um caminho de pacote configurável
  • Um caminho do ativo - o pacote inteiro que contém esse ativo é referenciado
  • Um URL
corvo vulcano
fonte
2

Escrevi um invólucro fácil que permite registrar estilos e scripts em todas as visualizações parciais dinamicamente na tag head.

Ele é baseado no DynamicHeader jsakamoto, mas apresenta algumas melhorias e ajustes de desempenho.

É muito fácil de usar e versátil.

O uso:

@{
    DynamicHeader.AddStyleSheet("/Content/Css/footer.css", ResourceType.Layout);    
    DynamicHeader.AddStyleSheet("/Content/Css/controls.css", ResourceType.Infrastructure);
    DynamicHeader.AddScript("/Content/Js/Controls.js", ResourceType.Infrastructure);
    DynamicHeader.AddStyleSheet("/Content/Css/homepage.css");    
}

Você pode encontrar o código completo, explicações e exemplos dentro: Adicione estilos e scripts dinamicamente ao cabeçalho

Amir Yonatan
fonte