CSS文件中的ASP.NET MVC URL自动解析

时间:2008-10-27 15:54:37

标签: asp.net asp.net-mvc

在正常的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应用程序将部署在〜根文件夹可能不明显的几个环境中。


编辑:我的意思是文件内容中的网址不是文件的网址。

6 个答案:

答案 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移动到我所有网站和页面中的脚本。

如果你问我,这是一个愚蠢的举动,但它在当前的测试版中是现实:(