【问题标题】:Implementing a css and javascript asset manager in ASP .NET MVC在 ASP .NET MVC 中实现 css 和 javascript 资产管理器
【发布时间】:2026-02-18 22:05:01
【问题描述】:

我目前实现了一个简单的资产管理器,它允许我在外部文件和内联文件中管理 CSS 和 JavaScript 资源。

我希望改进我在代码中使用它的方式,但我希望能够以这样一种方式使用它,以便可以从 both 我的辅助函数访问它和我的观点。

目前调用它我正在做这样的事情:

在我的助手中:

public void MyHelper(this HtmlHelper helper)
{
    JavascriptAssetManager.Current(helper.ViewData, typeof(JavascriptAssetManager)).Inline(@"alert('Some javascript!');");
}

在我看来:

<% CssAssetManager.Current(this.ViewData, typeof(CssAssetManager))
       .Add(Url.Content("~/Content/styles.css")); %>

我有两个 AssetManager 类实例(每个实例一个),我将它们存储在 ViewDataDictionary 中,这是我发现的唯一一种方法,我可以存储我的两个助手都可以访问的每页请求对象和我的看法。

我的 Current 方法在基本抽象类中实现(这就是为什么我必须将子对象的类型传递给该方法)。这允许我为 Javascript 和 CSS 实现单独的渲染函数(包括和内联语句)。

我的最终目标是修改解决方案,以便我可以像这样使用它:

public void MyHelper(this HtmlHelper helper)
{
    helper.Scripts.Inline(@"alert('whatever');");
}

<% Css.Add(Url.Content("~/Content/layout.css")); %>

我查看了其他解决方案,并尝试了一两个。即这个:http://weblogs.asp.net/rashid/archive/2009/05/02/script-and-css-management-in-asp-net-mvc-part-2.aspx

它确实非常好,但我发现在我的 HTML Helpers 中包含一些简单的 JS 令人讨厌...为了让 Lamba 动作发挥作用,我最终不得不执行以下操作:

() => { "alert('whatever');".ToString() }

试图将 C# 变量传递给它让我崩溃了……我更喜欢基于参数化 String.Format() 的内联方法(即使我不喜欢将花括号加倍)。

我的意思是:如果有人可以推荐一些效果很好的东西,我完全愿意废弃我的代码并只使用第三方的东西。 我真的很想管理 CSS 和 JavaScript。

这是我现在拥有的 Current 方法;我很乐意提供更多(全部)代码:

    public static BaseAssetManager Current(ViewDataDictionary ViewData, Type InstanceType)
    {
        string viewDataKey = InstanceType.Name + "-ViewData";

        //If not instanciated yet, create it:
        if (!ViewData.ContainsKey(viewDataKey) || ViewData[viewDataKey] == null)
        {
            var instance = (AbstractAssetManager)Activator.CreateInstance(InstanceType);
            ViewData[viewDataKey] = instance;
            return instance;
        }

        return (AbstractAssetManager)ViewData[viewDataKey];
    }

作为奖励,如果能够将 CSS 文件包含在我的助手/视图中,然后将其全部放入标签中,那就太好了。

我在我的解决方案中发现,由于我在母版页的标题处调用我的呈现代码,所以在我的视图中进行的任何包含调用都被忽略了。

大概是因为调用和编译东西的顺序。我最终只是在页面的页脚处渲染了所有的 CSS 来规避这一点,因为(现在)让我的助手在运行时确定页面上需要哪些文件对我来说更重要。

如果您愿意,请为我的这种不良做法发火,但我还没有达到任何优化它的需要。 :)

谢谢大家!

编辑:


根据@smartcaveman 的帖子,我一直在试用 Telerik Web Assets Styles and Scripts Registrars。似乎很大程度上基于我提到的博客文章,也许作者与他们有关?

Telerik 版本中有很多额外的功能,但有帮助的是 OnDocumentReady() 重载,它接受字符串来执行内联 Javascript。

我永远不会将内联 JS 用于任何主要的事情,但如果你将所有 JS 函数都放在外部文件中,它肯定会有所帮助,你可以动态地包含这些文件。然后,只要输入(HTML 助手等)需要调用该 JS 函数,只需进行一行调用。

它将 OnDocumentReady() 方法的所有调用组合到我的页脚中的单个 javascript 内联代码块中,我在其中调用了 Render()。

这正是我所追求的。

不幸的是,为样式表调用 Render() 似乎仍然受到同样的警告,即在进行渲染调用之后,任何包含的文件都不会被处理。希望有一个变通办法,但现在我很高兴。

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    Telerik 的 ASP.NET MVC 扩展具有出色的 Web 资产管理器。描述在这里:http://www.telerik.com/products/aspnet-mvc/web-asset-managers.aspx。您也可以从右侧面板下载开源代码。避免重新发明*通常是一个好主意,这个组件可以满足您的所有需求,甚至更多。

    【讨论】:

    • 我确实检查过,但我完全错过了开源下载链接。会检查的,谢谢!
    • 看起来不错。 Telerik 的经理似乎使用与该博客文章类似的语法,但至少它有 StyleSheet 管理!仍然需要研究用它注入内联 JS/CSS 的最佳方法。不过谢谢!
    • @Geekman,让我知道你的决定。我实际上正在做类似的事情。检查我目前未解决的问题:*.com/questions/5255223/…。这就是我现在的道路。
    • 刚刚发布了关于我现在如何做事的问题。 :)
    • @Geekman,如果你查看我的帖子,你会看到我为注册依赖项提出的解决方案。
    【解决方案2】:

    有一个运行良好的新 .net 开源资产管理器,名为 Cassette,托管在 Github 上。它具有简洁的语法,支持样式表、CoffeeScript 和 html 模板。如果您的网站处于生产状态(debug=false),它将最小化和组合脚本并根据文件哈希缓存它们。

    【讨论】:

      【解决方案3】:

      Telerik 的 ASP.NET MVC 扩展不是免费的。我最近遇到了以下解决方案:http://weblogs.asp.net/rashid/archive/2009/04/28/script-and-css-management-in-asp-net-mvc.aspx

      【讨论】:

      • 虽然 Telerik 扩展可能不是完全免费的,但有一个开源版本 - 可以被其他开源应用程序合法使用。我已经在几个应用程序中使用了它们。 telerik.com/products/aspnet-mvc/getting-started/licensing.aspx。不确定你是否看到了,但我确实链接到了 Rashid 博客上的一篇文章——我确实尝试过,但发现有些东西我不喜欢——我相信这个解决方案实际上是一个早期版本Telerik 发布的内容。据我了解,他为他们工作。
      • 你能在商业软件中免费使用 Telerik 的 ASP.NET MVC 扩展吗?
      • 我想没有什么能阻止你。但根据开源版本受约束的 GPL v2 协议,它是不合法的。我想如果您确实在商业应用中使用它,如果被发现,您将面临法律诉讼的风险。