将ASP.NET服务器脚本添加到大多数静态.JS / .CSS文件而不会丢失IntelliSense?

时间:2009-08-07 14:28:19

标签: javascript css visual-studio visual-studio-2008 intellisense

使用VS2008和ASP.NET 3.5(或VS 2010 / .NET 4.0?),如何在大多数静态JavaScript和CSS文件中包含一些动态ASP.NET服务器端代码?

我想这样做是为了避免克隆整个JS或CSS文件,只改变其中一小部分多租户网站。后来,我想扩展解决方案来处理javascript / CSS中的本地化,动态调试/跟踪支持,以及通过将内容动态注入JavaScript和CSS而获得的其他很酷的东西。

困难之处在于我不想丢失静态文件所带来的所有酷事,例如:

  • JS / CSS代码着色和智能感知
  • IDE中的CSS-class“转到定义”支持
  • 基于基础文件日期的自动HTTP缓存标头
  • IIS自动压缩

静态文件的服务器端优点(例如标题/压缩)可以通过HttpHandler伪造,但保留IDE优点(intellisense / coloring / etc)让我感到难过。

理想的解决方案将满足以下要求:

  1. VS IDE提供JS / CSS智能感知和代码着色。放弃服务器代码智能感知是可以的,因为这些文件中的服务器代码通常很简单。
  2. “go to defintion”仍适用于CSS类(就像在静态CSS文件中一样)
  3. 发送HTTP缓存标头,根据基础文件的修改日期而变化。
  4. 像其他静态文件一样支持HTTP压缩
  5. 支持<%=%>和< script runat = server>代码块
  6. URL路径(至少是HTTP客户端看到的路径)以.JS或.CSS(不是.ASPX)结尾。或者,我可以使用querystring或PathInfo进行参数化(例如选择一个区域设置),尽管在大多数情况下我会使用vdirs进行参数化。缓存应根据不同的查询字符串而有所不同。
  7. 到目前为止,我提出的最佳(hacky)解决方案是:

    • 将基础CSS或JS文件切换为.ASPX文件(例如foo.css.aspx或foo.js.aspx)。将底层静态内容嵌入STYLE元素(对于CSS)或SCRIPT元素(对于JS)。这使得JS / CSS智能感知以及允许内联或runat =服务器代码块。
    • 写一个HttpHandler:
      • 查看URL并添加.aspx以了解要调用的正确底层ASPX
      • 使用System.Net.HttpWebRequest来调用该URL
      • 删除包含STYLE或SCRIPT标记,只留下CSS或JS
      • 添加适当的标头(缓存,内容类型等)
      • 如果客户端支持压缩,则压缩响应
    • 将* .CSS和* .JS映射到我的处理程序。
    • (如果是IIS6)确保将.JS和.CSS文件扩展名映射到ASP.NET

    我已经使用了Darick_c的HttpCompression Module的修改版本,它可以处理我上面的几乎所有内容,所以修改它以支持上面的解决方案并不会太难。

    但我的解决方案很糟糕。我想知道是否有人对此问题采用更轻量级的方法,这不会失去Visual Studio的静态文件优点。

    我知道我也可以破解一个仅限客户端的解决方案,我将所有JS和CSS分成“变化”和“不会变化”的文件,但这种解决方案的性能和维护开销是我想避免。我真的想要一个服务器端解决方案,所以我可以在服务器上维护一个文件,而不是N + 1个文件。

    我还没有尝试过VS10 / .NET 4.0,但我对Dev10 / .net4解决方案持开放态度,如果这是使这种情况有效的最好方法。

    谢谢!

2 个答案:

答案 0 :(得分:3)

我通过让母版页在每个页面的页脚中输出动态生成的JSON对象来处理类似的问题。

我需要让我的js popup登录对话框支持本地化。因此,使用JSON.NET进行序列化,我创建了一个页面可以访问的母版页的公钥/值集合属性,以便将键/值放入短语键/本地化短语对中。然后,母版页呈现一个动态JSON对象,该对象包含这些值,以便静态js文件可以引用这些动态值。

对于js登录框,我让母版页设置了本地化的值。这是有道理的,因为母版页还包含login.js文件。

答案 1 :(得分:1)

我确实对您对从客户端发出的http请求数量以及返回的有效负载的关注表示赞赏​​。我认识和工作的人太多,忽略了那些简单的优化。但是,任何时候我遇到你遇到的同一个问题(实际上经常是这样),我发现我通常要么在某个地方转错,要么试图以错误的方式解决问题。

就你的JS问题而言,我认为Frank Schwieterman在上面的评论中是正确的。我将研究如何通过setter公开JS的动态部分。一个非常基本的例子是,如果您想要在登录时向用户显示自定义欢迎消息。在JS文件中,您可以公开setMessage(message)方法。然后,包含脚本的页面将调用该方法。结果,你有类似的东西:

<body onLoad="setMessage('Welcome' + <%= user.FirstName %>);">

显然可以通过将对象或方法传递到静态JS文件来扩展,以便为您提供所需的功能。

在回答CSS问题时,我认为你可以从Shawn Steward的评论中获得很多好处。您可以在基本文件中定义CSS的某些静态部分,然后在其他文件中重新定义要更改的部分。因此,您可以根据您所包含的文件来决定您网站的外观。此外,因为您不想接受额外的http请求(请记住,如果您将这些文件设置为缓存一周,一个月等,这是一次性请求),您可以执行类似组合的操作CSS文件在编译或运行时编译成单个文件。

以下链接可能有助于您指明正确的方向:

http://geekswithblogs.net/rashid/archive/2007/07/25/Combine-Multiple-JavaScript-and-CSS-Files-and-Remove-Overheads.aspx

http://www.asp.net/learn/3.5-SP1/video-296.aspx?wwwaspnetrdirset=1

http://dimebrain.com/2008/04/resourceful-asp.html

通过在运行或编译时利用组合,您可以通过允许逻辑上分离CSS和JS文件来获得两全其美,同时还可以减少压缩和组合文件带来的有效负载和请求。