在正常的WebForms场景中,任何根目录相对的URL(例如〜/ folder / file.txt)内部 CSS文件,例如:
.form { background-image: url(~/Content/Images/form_bg.gif); }
如果我指定,将在运行时自动解析
<head runat="server">
在引用页面中。
但是,ASP.NET MVC Beta1网站上不再发生这种情况。
有没有办法在不诉诸hacks或CSS-loader文件的情况下启用此功能?就像HttpModules或者什么?
或者我没有正确地设计我的网站?什么应该是一个好的设计?
由于原始ASP.NET WebForms已经具有此功能,因此我更愿意使用任何现有功能。但我没有太多线索。
此Web应用程序将部署在〜根文件夹可能不明显的几个环境中。
编辑:我的意思是文件内容中的网址不是文件的网址。
答案 0 :(得分:46)
我不打扰使用自动根查找~
字符。我知道您希望在部署之间根目录不同的地方使用相同的解决方案,但在CSS文档中,使用相对路径时不应该有任何问题。 CSS文档中的路径(到示例中的图像URL)将始终相对于CSS文件的位置,而不管加载该CSS文件的任何页面的路径如何。因此,如果您的图片位于~/Content/Images
且样式表位于~/Content/Stylesheets
,则您始终可以使用background-image: url(../Images/form_bg.gif);
,无论加载样式表的网页位置如何,它都能正常运行
这有什么理由不起作用吗?
答案 1 :(得分:5)
我过去使用的一个技巧是实际上使我的CSS文件具有.ASPX扩展名,并在页面签名中设置ContentType属性:
<%@ Page Language="C#" ContentType="text/css" %>
body {
margin: 0;
padding: 0;
background: #C32605 url(<%= ResolveUrl("~/Content/themes/base/images/BodyBackground.png") %>) repeat-x;
font-family: Verdana, Arial, sans-serif;
font-size: small;
color: #d7f9ff;
}
这将确保CSS文件通过ASP.NET框架,并用相对路径替换服务器端代码。
答案 2 :(得分:4)
Here are some resources关于实施IHttpModule拦截对您应用的网络请求...
编写/改编一个以检查文件类型(例如伪代码:if(请求以“.css”结尾)...)
然后使用正则表达式将所有“〜/”实例替换为System.Web.VirtualPathUtility.ToAbsolute(“〜/”)
我不知道这会对性能产生什么作用,通过这种过滤器运行每个请求,但是您可能会使用您的web.config文件和/或您的MVC URL路由来汇总所有.css请求这种过滤器,同时跳过其他文件。
想想看,你可以在ASP.NET MVC应用程序中实现相同的效果,将所有CSS引用指向一个特殊的controller.action,为你执行这种预处理。我怀疑它会像IHttpModule一样高效。
答案 3 :(得分:1)
如果您尝试解析任何文件中的〜/ ,包括文本文件,javascript等,您可以编写一个处理程序来为其分配过滤器,您可以使用它来搜索这些路径......例如......
public class StringParsingFilter : MemoryStream {
public Stream OriginalStream {
get { return this.m_OriginalStream; }
set { this.m_OriginalStream = value; }
}
private System.IO.Stream m_OriginalStream;
public StringParsingFilter() : base() {
this.m_OriginalStream = null;
}
public override void Flush() {
this.m_OriginalStream.Flush();
}
public override void Write(byte[] buffer, int offset, int count) {
//otherwise, parse for the correct content
string value = System.Text.Encoding.Default.GetString(buffer);
string contentType = HttpContext.Current.Response.ContentType;
//Do any parsing here
...
//write the new bytes to the stream
byte[] bytes = System.Text.Encoding.Default.GetBytes(value);
this.m_OriginalStream.Write(bytes, offset, count + (bytes.Length - buffer.Length));
}
}
您将编写一个自定义处理程序,以了解何时分配此过滤器...如下所示......
public class FilterControlModule : IHttpModule {
public void Init(HttpApplication context) {
HttpApplication oAppContext = context;
oAppContext.BeginRequest += new EventHandler(_HandleSettingFilter);
}
private void _HandleSettingFilter(object sender, EventArgs e) {
//You might check the file at this part to make sure
//it is a file type you want to parse
//if (!CurrentFile.isStyleSheet()) { return; }
...
//assign the new filter
StringParsingFilter filter = new StringParsingFilter();
filter.OriginalStream = HttpContext.Current.Response.Filter;
HttpContext.Current.Response.Filter = (Stream)filter;
}
}
实际上只是说“查找IHttpModules”可能更容易,但这是我用来解析ASP.net文件以外路径的文件的一些代码。
您还必须更改IIS设置中的某些内容,以便通过将ASP.net ISAPI设置为所有处理文件的通配符来解析文件。如果您使用的是IIS6,则可以看到更多at this website
你也可以使用它来修改任何文件类型,这样你就可以为图像分配一些过滤器,一些用于javascript或样式表,或者......真的有......
答案 4 :(得分:0)
您可以使用URL Rewriter在请求进入时修复网址,但我不确定它在这种情况下是否像黑客一样优雅。
答案 5 :(得分:0)
我创建了一个PathHelper util类,它为我提供了所需的所有路径。 例如
<link href="<%=PathHelper.CssUrl("FormulaIndex.css")%>" rel="Stylesheet" type="text/css"/>
在System.Web.VirtualPathUtility.ToAbsolute()和我自己的约定(content / css / yourFile.css)的帮助下,给我正确的完整网址。
我为js,xml,t9n,pics做了同样的事...... 它的核心,可重用,现在我只需更改一行来捕获脚本文件夹从content / js移动到我所有网站和页面中的脚本。
如果你问我,这是一个愚蠢的举动,但它在当前的测试版中是现实:(