Agregue archivos CSS o JavaScript al encabezado de diseño desde vistas o vistas parciales

176

Diseño de encabezado de páginas:

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

Una vista (AnotherView) de la aplicación necesita:

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

y AnotherView tiene una vista parcial (AnotherPartial) que necesita:

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

Pregunta: ¿Cómo podemos agregar estos enlaces de archivos CSS a los enlaces AnotherView y AnotherPartial al encabezado de diseño ?

RenderSection no es una buena idea porque AnotherPage puede tener más de un Parciales. Agregar todo CSS al encabezado no es útil porque cambiará dinámicamente (depende de Anotherpages).

Nuri YILMAZ
fuente
@NuriYILMAZ es una gran diferencia entre "desde vistas" y "o vistas parciales" según su título. De todos modos, ¿alguna idea nueva al respecto?
Shimmy Weitzhandler

Respuestas:

196

Diseño:

<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>

Ver:

@model ProjectsExt.Models.DirectoryObject

@section AddToHead{
    <link href="@Url.Content("~/Content/Upload.css")" rel="stylesheet" type="text/css" />
}
RouR
fuente
55
Creo que esta es la solución más simple.
iamichi
¡Una solución lista para usar!
jerrylroberts
14
Eso no funcionará si la AddToHeadsección está en una vista parcial incrustada en View.
Shimmy Weitzhandler
57
¡La pregunta mencionó específicamente la vista parcial y esta respuesta mejor calificada no aborda el problema! Esta puede ser una excelente solución para otra consulta, pero no esta.
Cuervo vulcano
1
Habría sido una solución elegante si funcionara de forma aguda con vistas parciales.
Jonny
75

Actualización : ejemplo básico disponible en https://github.com/speier/mvcassetshelper

Estamos utilizando la siguiente implementación para agregar archivos JS y CSS en la página de diseño.

Vista o Vista parcial:

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

Página de diseño:

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

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

Extensión 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
fuente
2
@JBeckton: Eche un vistazo al código y reemplace los Insertmétodos con Addmétodos
Valamas
9
@Kalman: la seguridad de este hilo se ha cuestionado (bastante correctamente desde mi punto de vista): stackoverflow.com/questions/6609586/…
Marc Gravell
2
Esto está muy mal; debe ser [ThreadStatic], o, preferiblemente, almacenado en HttpContext.Items.
Slaks
66
¿Me estoy perdiendo de algo? Si se llama a Styles.Render () en <head>, los archivos css agregados después de <head> (es decir, archivos agregados en vistas parciales) no se procesarán. (MVC representa de arriba a abajo.)
Ken
3
@FernandoCorreia Creo que te equivocaste. Las secciones con nombre no funcionan en vistas parciales, que es la base de todo este hilo.
Shimmy Weitzhandler
11

Lamentablemente, esto no es posible por defecto a usar sectioncomo otro usuario sugirió, ya que una sectionestá disponible sólo a lo inmediato childde un View.

Sin embargo, lo que funciona es implementar y redefinir sectionen cada vista , lo que significa:

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

De esta manera, cada vista puede implementar una sección principal, no solo los elementos secundarios inmediatos. Sin embargo, esto solo funciona en parte, especialmente con múltiples parciales que comienzan los problemas (como ha mencionado en su pregunta).

Entonces, la única solución real a su problema es usar el ViewBag. Lo mejor probablemente sería una colección separada (lista) para CSS y scripts. Para que esto funcione, debe asegurarse de que lo Listutilizado se inicialice antes de ejecutar cualquiera de las vistas. Entonces puede hacer cosas como esta en la parte superior de cada vista / parcial (sin importar si el valor Scriptso Styleses nulo:

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

En el diseño, puede recorrer las colecciones y agregar los estilos basados ​​en los valores de 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" />
}

Creo que es feo, pero es lo único que funciona.

****** ACTUALIZACIÓN **** Dado que primero comienza a ejecutar las vistas internas y avanza hacia el diseño y los estilos CSS están en cascada, probablemente tendría sentido invertir la lista de estilos a través de ViewBag.Styles.Reverse().

De esta manera, se agrega primero el estilo más externo, que está en línea con la forma en que funcionan las hojas de estilo CSS.

ntziolis
fuente
1
Gracias ntziolis. Parece bonito, pero los cabezales de diseño de la maquinilla de afeitar funcionan primero antes de otras vistas, y las dinámicas .scripts y .styles estaban vacías antes de otras vistas. Encontré un buen blog al respecto y compartí esta pregunta.
Nuri YILMAZ
Esto funcionará para cualquier vista derivada pero no para parciales. Para los parciales, de hecho, el orden de ejecución es incorrecto. básicamente para parciales no hay forma de incluirlos en el encabezado. Sugeriría, en lugar de agregarlo al encabezado, simplemente agréguelo al comienzo de la etiqueta del cuerpo. No sería mi primera opción, pero de esta manera tiene una forma concisa de administrar todos los estilos / js en un solo lugar, en lugar de dispersarlos.
ntziolis
Estoy de acuerdo contigo. Porque encontré algunas soluciones que enumeré en la respuesta, pero son exactamente soluciones js. Realmente me pregunto por qué no podríamos usar la página de diseño como asp.net clásica. Significa que puedo llegar a la cabeza desde la página secundaria.
Nuri YILMAZ
11

Puede definir la sección por el método RenderSection en el diseño.

Diseño

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

Luego puede incluir sus archivos css en el área de sección en su vista, excepto la vista parcial .

La sección funciona a la vista, pero no funciona en vista parcial por diseño .

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

Si realmente desea utilizar el área de sección en vista parcial, puede seguir el artículo para redefinir el método RenderSection.

Maquinilla de afeitar, diseños anidados y secciones redefinidas - Marcin en ASP.NET

Ordeñador
fuente
6

Tuve un problema similar y terminé aplicando la excelente respuesta de Kalman con el código a continuación (no tan ordenado, pero podría decirse que más expansible):

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>";
    }
}

El proyecto contiene un 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");     

en la página _layout

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

y en los parciales y vistas

Html.Assets().Libraries.Uses("DataTables");
Html.Assets().AddScript("~/Scripts/emailGridUtilities.js");
Brent
fuente
Interesante. Parece excesivo, pero veo que esto se usa más con sitios web que no tienen otra opción, sino para tratar con usuarios que usan versiones anteriores de ie ... como en entornos corporativos donde algunos países no se han actualizado, y usted quiere dispararse a sí mismo. jajaja +1 para eso
pqsk
5

Traté de resolver este problema.

Mi respuesta esta aquí.

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

Por ejemplo, _Layout.cshtml es:

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

Y puede registrar archivos .js y .css en "DynamicHeader" en cualquier lugar que desee.

Por ejemplo, el bloque de código en AnotherPartial.cshtm es:

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

Entonces, finalmente el HTML de salida es:

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

Pruebe la solución lista para usar (ASP.NET MVC 4 o posterior):

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

    bundle.Include("~/Scripts/myFile.js");
}
RouR
fuente
Recibo un error:CS0103: The name 'BundleTable' does not exist in the current context
Kunal
nvm: lo resolvió. Tuve que agregar System.Web.Optimizationes decirSystem.Web.Optimization.BundleTable.Bundles.GetRegisteredBundles().First(b => b.Path == "~/bundles/css");
Kunal
1
¿No modifica esto el paquete globalmente? Si hace esto en la página A y luego abre la página B, la página B también incluirá myFile.js que no creo que fuera querido por el OP
miles82
4

Para aquellos de nosotros que usamos ASP.NET MVC 4, esto puede ser útil.

Primero, agregué una clase BundleConfig en la carpeta App_Start.

Aquí está mi código que usé para crearlo:

using System.Web.Optimization;

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

En segundo lugar, registré la clase BundleConfig en el archivo Global.asax:

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

Tercero, agregué ayudantes de estilo al mi archivo 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;
}

Finalmente utilicé esta sintaxis en cualquier Vista:

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

Aquí hay un complemento NuGet llamado Cassette , que entre otras cosas le brinda la capacidad de hacer referencia a scripts y estilos en parciales.

Aunque hay una serie de configuraciones disponibles para este complemento, lo que lo hace altamente flexible. Aquí está la forma más simple de referir archivos de script u hojas de estilo:

Bundles.Reference("scripts/app");

De acuerdo con la documentación :

Las llamadas a Referencepueden aparecer en cualquier lugar de una página, diseño o vista parcial.

El argumento de ruta puede ser uno de los siguientes:

  • Un camino de paquete
  • Una ruta del activo: se hace referencia a todo el paquete que contiene este activo
  • Una URL
cuervo vulcano
fuente
2

Escribí un contenedor fácil que le permite registrar estilos y secuencias de comandos en cada vista parcial de forma dinámica en la etiqueta principal.

Se basa en el DynamicHeader jsakamoto presentado, pero tiene algunas mejoras de rendimiento y ajustes.

Es muy fácil de usar y versátil.

El 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");    
}

Puede encontrar el código completo, explicaciones y ejemplos en el interior: Agregar estilos y secuencias de comandos dinámicamente a la etiqueta de encabezado

Amir Yonatan
fuente