从视图或部分视图向布局头添加 CSS 或 JavaScript 文件

版面设计页首:

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

来自应用程序的视图(AnotherView)需要:

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

AnotherView 有一个局部视图(AnotherPart) ,它需要:

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

问: 我们如何才能 这些 CSS 文件链接 另一视图和另一部分到布局头的链接

RenderSection 不是一个好主意,因为 AnotherPage 可以有多个 Partials。将所有 CSS 添加到 head 是没有用的,因为它会动态更改(它取决于 Anotherpage)。

249015 次浏览

遗憾的是,默认情况下不可能像其他用户建议的那样使用 section,因为 section只对 View的直接 child可用。

然而,有效的是 在每个视图中实现和重新定义 section,意思是:

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

这样每个视图都可以实现头部部分,而不仅仅是直接的子视图。这只是部分工作,特别是与多个部分的麻烦开始(正如你在你的问题中提到)。

因此,解决问题的唯一真正方法是使用 ViewBag。最好的方法可能是为 CSS 和脚本提供一个单独的集合(列表)。为此,您需要确保在执行任何视图之前初始化所使用的 List。然后你可以在每个视图/部分的顶部做这样的事情(不用管 Scripts或者 Styles值是否为 null:

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

然后在布局中循环遍历集合,并根据 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" />
}

我觉得很丑,但这是唯一有效的方法。

最新消息 由于它首先开始执行内部视图,然后逐渐进入布局,并且 CSS 样式正在级联,所以通过 ViewBag.Styles.Reverse()逆转样式列表可能是有意义的。

这样,首先添加最外层的样式,这与 CSS 样式表的工作方式是内联的。

更新 : 可在 < a href = “ https://github.com/speier/mvcassetshelper”rel = “ norefrer”> https://github.com/speier/mvcassetshelper 获得的基本示例

我们使用以下实现将 JS 和 CSS 文件添加到布局页面中。

视图或部分视图:

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

布局页面:

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


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

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

布局:

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

观看内容:

@model ProjectsExt.Models.DirectoryObject


@section AddToHead{
<link href="@Url.Content("~/Content/Upload.css")" rel="stylesheet" type="text/css" />
}

我试图解决这个问题。

我的答案就在这里。

“ DynamicHeader”-http://dynamicheader.codeplex.com/https://nuget.org/packages/DynamicHeader

例如,_ Layout.cshtml 是:

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

并且,您可以将.js 和.css 文件注册到您想要的“ DynamicHeader”任何地方

例如,AnotherPartial.cshtml 中的代码块是:

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

结果此示例的 HTML 输出为:

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

我也遇到过类似的问题,最后我用下面的代码应用了 Kalman 的优秀答案(虽然不那么简洁,但可以说更具可扩展性) :

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

该项目包含一个静态 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");

在 _ laypage 中

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

以及在部分(s)和视图中

Html.Assets().Libraries.Uses("DataTables");
Html.Assets().AddScript("~/Scripts/emailGridUtilities.js");

我编写了一个简单的包装器,允许您在每个部分视图中动态地将样式和脚本注册到 head 标记中。

它是基于 DynamicHeader jsakamoto 提出的,但它有一些性能改进和调整。

它非常容易使用,而且通用。

用法:

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

你可以在里面找到完整的代码、解释和示例: 动态添加样式和脚本到头标签

下面是一个名为 卡带NuGet插件,它提供了以部分形式引用脚本和样式的功能。

虽然这个插件有 许多配置可用,这使得它非常灵活。下面是引用脚本或样式表文件的最简单方法:

Bundles.Reference("scripts/app");

根据 文件:

Reference的调用可以出现在页面、布局或部分视图中的任何位置。

Path 参数可以是下列参数之一:

  • 一条捆绑路径
  • 资产路径-包含这个资产的整个捆绑包被引用
  • 一个网址

尝试开箱即用的解决方案(ASP.NET MVC 4或更高版本) :

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


bundle.Include("~/Scripts/myFile.js");
}

对于我们这些使用 ASP.NET MVC 4的人来说,这可能是有帮助的。

首先,我在 App _ Start 文件夹中添加了一个 BundleConfig 类。

下面是我用来创建它的代码:

using System.Web.Optimization;


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

其次,我在 Global.asax 文件中注册了 BundleConfig 类:

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

第三,我在 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;
}

最后,我在任何视图中都使用了这种语法:

@Styles.Render("~/Content/css")

可以通过布局中的 渲染部门方法定义节。

布局

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

然后您可以包括您的 css 文件在部分区域在您的意见 除了部分景观

本节工作在视图中,但不能在局部视图中工作

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

如果确实希望在部分视图中使用 section 区域,可以按照本文的内容重新定义 RenderSection 方法。

Razor,嵌套布局和重新定义的节 & # 8211; Marcin 在 ASP.NET 上