尝试从部分视图中将JS和CSS添加到MVC 3 Razor网站中的布局文件中

Dan*_*röm 7 c# asp.net razor asp.net-mvc-3

我目前正在使用类似于以下代码的方法将脚本和css文件添加到布局文件的头部.

public static class HtmlHelperExtensions
{
    public static MyCompanyHtmlHelpers MyCompany(this HtmlHelper htmlHelper)
    {
        return MyCompanyHtmlHelpers.GetInstance(htmlHelper);
    }    
}

public class MyCompanyHtmlHelpers
{
    private static MyCompanyHtmlHelpers _instance;

    public static MyCompanyHtmlHelpers GetInstance(HtmlHelper htmlHelper)
    {
        if (_instance == null)
            _instance = new MyCompanyHtmlHelpers();

        _instance.SetHtmlHelper(htmlHelper);

        return _instance;
    }

    private HtmlHelper _htmlHelper;

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

    public MyCompanyHtmlHelpers()
    {
        Styles = new ItemRegistrar(ItemRegistrarFromatters.StyleFormat);
        Scripts = new ItemRegistrar(ItemRegistrarFromatters.ScriptFormat);
    }

    private void SetHtmlHelper(HtmlHelper htmlHelper)
    {
        _htmlHelper = htmlHelper;
    }
}

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

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

    public ItemRegistrar Add(string url)
    {
        if (!_items.Contains(url))
            _items.Insert(0, 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 ItemRegistrarFromatters
{
    public const string StyleFormat = "<link href=\"{0}\" rel=\"stylesheet\" type=\"text/css\" />";
    public const string ScriptFormat = "<script src=\"{0}\" type=\"text/javascript\"></script>";
}
Run Code Online (Sandbox Code Playgroud)

使用Html.MyCompany().Styles.Add("/Dashboard/Content/Dashboard.css");添加文件...而且@Html.MyCompany().Styles.Render()使它们在Layout_.cshtml.

我的问题是这是一个静态方法,这意味着它会持久保存样式表和脚本文件列表.

我需要做同样的事情,但不保持持久性.

我需要在每个请求上重新创建列表,因为它们会在页面之间更改该特定页面上的外观.

是否可以在添加所需的脚本之前或者在渲染完之后清除每个请求上的列表?

更新: 不使用节,RenderPartial或RenderaActions的原因是为了防止将相同的样式表或脚本文件多次添加到布局文件中.

网站im建筑有一个Layout_.cshtml,基本布局.这反过来由循环使用项目列表的视图使用,并且对于每个项目调用RenderAction,其输出该项目的特定局部视图.这些部分视图有时需要添加样式表和脚本.

由于可能需要从不同的部分视图中添加许多不同的脚本和样式表,因此我认为可以完成样式和脚本的全局列表,因此有一个全局位置可以检查脚本是否已经全部添加到集合中或不然后按照添加的顺序一次性渲染它们.

更新2: 真正的问题是如何使用相同类型的函数(全局列表)但不使用静态Extension方法.

Mar*_*ell 9

我会用部分来做,即

@section head {
    ...add whatever you want here...
}
Run Code Online (Sandbox Code Playgroud)

并从布局中渲染"head"部分:

<head>
...other stuff here...
@RenderSection("head", required: false)
</head>
Run Code Online (Sandbox Code Playgroud)

如果你不想要部分,并且不想传递它,我会在这里使用HttpContext; 存储一些数据HttpContext.Current.Items[someKey].如果为null,则创建一个新的并将其存储在上下文中.

例如:

public static MyCompanyHtmlHelpers GetInstance(HtmlHelper htmlHelper)
{
    const string key = "MyCompanyHtmlHelpersInstance";
    IDictionary items = (htmlHelper == null || htmlHelper.ViewContext == null
        || htmlHelper.ViewContext.HttpContext == null)
        ? HttpContext.Current.Items : htmlHelper.ViewContext.HttpContext.Items;

    MyCompanyHtmlHelpers obj = (MyCompanyHtmlHelpers)items[key];
    if (obj == null)
    {
        items.Add(key, obj = new MyCompanyHtmlHelpers());
    }
    return obj;
}
Run Code Online (Sandbox Code Playgroud)