187

Layout pages head:

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

A View (AnotherView) from the application needs:

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

and AnotherView has a partial view (AnotherPartial) which needs:

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

Question: How can we add these CSS files links AnotherView and AnotherPartial links to Layout head?

RenderSection is not a good idea because AnotherPage can have more than one Partials. Add all CSS to head is not useful because it will change dynamicaly (it depends on Anotherpages).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nuri YILMAZ
  • 4,291
  • 5
  • 37
  • 43

10 Answers10

210

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>

View:

@model ProjectsExt.Models.DirectoryObject

@section AddToHead{
    <link href="@Url.Content("~/Content/Upload.css")" rel="stylesheet" type="text/css" />
}
lc.
  • 113,939
  • 20
  • 158
  • 187
RouR
  • 6,136
  • 3
  • 34
  • 25
80

Update: basic example available at https://github.com/speier/mvcassetshelper

We are using the following implementation to add JS and CSS files into the layout page.

View or PartialView:

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

Layout page:

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

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

HtmlHelper extension:

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>";
}
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
Kalman Speier
  • 1,937
  • 13
  • 18
  • Hi Kalman! It is another nice solution. I will try one of them for my apps. :) I like your code more because it is "pure code". Thanks. – Nuri YILMAZ Mar 01 '11 at 15:48
  • one problem with this solution... it does not maintain the order in which I call the scripts to be loaded. Actually they are reversed order. – JBeckton Mar 16 '11 at 00:43
  • 2
    @JBeckton: Have a look in the code and replace `Insert` methods with `Add` methods – Valamas Jul 06 '11 at 05:48
  • @Kalman Speier: thank you so much for this. I am using it to collect any document.ready type statements. – Valamas Jul 07 '11 at 10:56
  • 9
    @Kalman - the thread-safety of this has (quite correctly in my view) been called into question: http://stackoverflow.com/questions/6609586/is-this-html-helper-thread-safe/ – Marc Gravell Jul 07 '11 at 11:15
  • This approach doesn't work if you register your client resource in @section of the View because it is called via execute method of layout: – Ilya Builuk Oct 12 '11 at 11:43
  • 2
    This is very wrong; it should be `[ThreadStatic]`, or, preferably, stored in `HttpContext.Items`. – SLaks Nov 20 '11 at 16:19
  • 2
    Updated to store the AssetsHelper class instance in the current HttpContext as mentioned by @SLaks – Kalman Speier Dec 21 '11 at 11:45
  • It would be better to use the `HttpContextBase` from the `HtmlHelper`. – SLaks Dec 21 '11 at 13:21
  • 1
    Updated to use `HttpContextBase` from `HtmlHelper`'s `ViewContext` as mentioned by @SLaks – Kalman Speier Dec 21 '11 at 14:08
  • 6
    Am I missing something? If Styles.Render() is called in , then any css files added after (i.e. files added in partial views) will not be rendered. (MVC renders from top to bottom.) – qxn Feb 10 '12 at 21:37
  • Views processed before the layout, see explanation: http://stackoverflow.com/a/8194454/438062 – Kalman Speier Feb 11 '12 at 10:04
  • I just tried this method and I get lot of [Namespace].[Class].ItemRegistrar values getting output in the head and body of the page... I can't see where it is coming from though. Any ideas? – yu_ominae Feb 15 '12 at 08:48
  • 1
    It's happening when you double prefix the Html helper with an '@' sign in your view. Check my example on GitHub https://github.com/speier/mvcassetshelper to see how to use. – Kalman Speier Feb 18 '12 at 11:47
  • How can this be added to asp.net mvc 2? – Dejan.S Mar 15 '12 at 14:33
  • An alternative that doesn't require helpers would be to use [named sections](http://stackoverflow.com/a/4311876/376366). – Fernando Correia Nov 12 '12 at 23:31
  • 3
    @FernandoCorreia I think you got it all wrong. Named sections do not work in partial views which is the base of this entire thread. – Shimmy Weitzhandler Dec 31 '12 at 23:45
  • @Shimmy I understand now. If you need partial views this helper is a great solution. – Fernando Correia Feb 25 '13 at 12:28
  • Hi, thank you, your answer worked well. Wanted to keep the standard virtual path references to my bundles. I ended up modifying your answer. Recap: • Made the ItemRegistrar abstract and used it as a base derived class to create [ScriptItemRegistrar] and [StyleItemRegistrar]. • Modified your implementation of Render and made it a abstract method. • New render then uses similar code to yours, but I create script tags without using string format. I use Scripts.Render() and Styles.Render() for abstract implementation. – B.Spangenberg Feb 09 '21 at 12:24
13

You can define the section by RenderSection method in layout.

Layout

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

Then you can include your css files in section area in your view except partial view.

The section work in view, but not work in partial view by design.

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

If you really want to using section area in partial view, you can follow the article to redefine RenderSection method.

Razor, Nested Layouts and Redefined Sections – Marcin On ASP.NET

pieperu
  • 2,662
  • 3
  • 18
  • 31
Milkker
  • 391
  • 1
  • 4
  • 10
12

Sadly, this is not possible by default to use section as another user suggested, since a section is only available to the immediate child of a View.

What works however is implementing and redefining the section in every view, meaning:

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

This way every view can implement a head section, not just the immediate children. This only works partly though, especially with multiple partials the troubles begin (as you have mentioned in your question).

So the only real solution to your problem is using the ViewBag. The best would probably be a seperate collection (list) for CSS and scripts. For this to work, you need to ensure that the List used is initialized before any of the views are executed. Then you can can do things like this in the top of every view/partial (without caring if the Scripts or Styles value is null:

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

In the layout you can then loop through the collections and add the styles based on the values in the 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" />
}

I think it's ugly, but it's the only thing that works.

******UPDATE**** Since it starts executing the inner views first and working its way out to the layout and CSS styles are cascading, it would probably make sense to reverse the style list via ViewBag.Styles.Reverse().

This way the most outer style is added first, which is inline with how CSS style sheets work anyway.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ntziolis
  • 10,091
  • 1
  • 34
  • 50
  • 1
    Thanks ntziolis. It is look like nice but, razor layout heads work first before another views, and .scripts and .styles dynamics was empty before another views. I found nice blog about it and I shared this question. – Nuri YILMAZ Feb 25 '11 at 01:44
  • This will work for any *derived* view but not for partials. For partials indeed the order of execution is wrong. basically for partials there is no way to include them into the header. I would suggest, instead of adding it to the header just add it in the beginning of the body tag. It would not be my first choice, but this way you have a concise way of managing all styles/js in one place, rather that scatter them around. – ntziolis Feb 25 '11 at 08:38
  • I'm aggree with you. Because I found some solutions as I listed on answer but it is exactly js solutions. I'm really wondering why we could not use layout page as clasic asp.net. It means I can reach to head from child page. – Nuri YILMAZ Feb 27 '11 at 14:32
7

I tried to solve this issue.

My answer is here.

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

For example, _Layout.cshtml is:

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

And, you can register .js and .css files to "DynamicHeader" anywhere you want.

For example, the code block in AnotherPartial.cshtml is:

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

Result HTML output for this sample is:

<html>
  <link href="/myapp/Content/themes/base/AnotherPartial.css" .../>
  <script src="/myapp/some/myscript.js" ...></script>
</html>
...
Michael
  • 3,982
  • 4
  • 30
  • 46
jsakamoto
  • 146
  • 2
  • 6
6

I had a similar problem, and ended up applying Kalman's excellent answer with the code below (not quite as neat, but arguably more 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>";
    }
}

The project contains a static AssignAllResources method:

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

in the _layout page

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

and in the partial(s) and views

Html.Assets().Libraries.Uses("DataTables");
Html.Assets().AddScript("~/Scripts/emailGridUtilities.js");
Brent
  • 4,611
  • 4
  • 38
  • 55
  • Interesting. Seems like overkill, but I do see this being used more with websites that have no choice, but to deal with users using older versions of ie...like in corporate environments where some countries have not upgraded, and you want to shoot yourself. lol. +1 for that – pqsk Dec 20 '13 at 15:16
4

Here is a NuGet plugin called Cassette, which among other things provides you the ability to reference scripts and styles in partials.

Though there are a number of configurations available for this plugin, which makes it highly flexible. Here is the simplest way of referring script or stylesheet files:

Bundles.Reference("scripts/app");

According to the documentation:

Calls to Reference can appear anywhere in a page, layout or partial view.

The path argument can be one of the following:

  • A bundle path
  • An asset path - the whole bundle containing this asset is referenced
  • A URL
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vulcan raven
  • 32,612
  • 11
  • 57
  • 93
4

Try the out-of-the-box solution (ASP.NET MVC 4 or later):

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

    bundle.Include("~/Scripts/myFile.js");
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
RouR
  • 6,136
  • 3
  • 34
  • 25
  • I am getting an error: `CS0103: The name 'BundleTable' does not exist in the current context` – Kunal Sep 19 '17 at 19:54
  • nvm: resolved it. Had to append `System.Web.Optimization` i.e. `System.Web.Optimization.BundleTable.Bundles.GetRegisteredBundles().First(b => b.Path == "~/bundles/css");` – Kunal Sep 19 '17 at 19:56
  • 3
    Doesn't this modify the bundle globally? If you do this on page A and later open page B, page B will also have myFile.js included which I don't think was wanted by the OP – miles82 Mar 15 '18 at 10:13
4

For those of us using ASP.NET MVC 4 - this may be helpful.

First, I added a BundleConfig class in the App_Start folder.

Here’s my code that I used to create it:

using System.Web.Optimization;

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

Second, I registered the BundleConfig class in the Global.asax file:

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

Third, I added style helpers to the my CSS file:

/* 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;
}

Finally I used this syntax in any View:

@Styles.Render("~/Content/css")
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Terry H
  • 327
  • 5
  • 11
2

I wrote an easy wrapper that allows you to register styles and scrips in every partial view dynamically into the head tag.

It is based on the DynamicHeader jsakamoto put up, but it has some performance improvements & tweaks.

It is very easy to use, and versatile.

The usage:

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

You can find the full code, explanations and examples inside: Add Styles & Scripts Dynamically to Head Tag

Amir Yonatan
  • 717
  • 1
  • 7
  • 14