ASP.NET MVC URL-авторазрешение в файлах CSS - PullRequest
27 голосов
/ 27 октября 2008

В обычном сценарии WebForms любые относящиеся к корню URL-адреса (например, ~ / folder / file.txt) внутри CSS-файлы, такие как:

.form { background-image: url(~/Content/Images/form_bg.gif); }

будет автоматически разрешено во время выполнения, если я укажу

<head runat="server">

На странице ссылок.

Однако этого больше не происходит на веб-сайте ASP.NET MVC Beta1.

Есть ли способ, которым я мог бы включить эту функцию, не прибегая к хаки или файл CSS-загрузчик? Как, может быть, HttpModules или что-то?

Или я неправильно определяю свой веб-сайт? Каким должен быть хороший дизайн?

Поскольку в исходных веб-формах ASP.NET эта функция уже есть, я бы предпочел использовать любые существующие функции, если это возможно. Но я понятия не имею.

Это веб-приложение будет развернуто в нескольких средах, где корневая папка может быть неочевидной.


РЕДАКТИРОВАТЬ: Я имею в виду URL-адрес в файле CONTENT, а не сам URL-адрес файла.

Ответы [ 6 ]

46 голосов
/ 06 ноября 2008

Я бы не стал возиться с автоматическим поиском корня символа ~. Я понимаю, что вы хотите, чтобы одно и то же решение работало там, где корневой каталог отличается при развертывании, но в документе CSS у вас не должно возникнуть проблем с использованием относительных путей. Пути в документе CSS (к URL-адресу изображения в вашем примере) всегда будут относительно местоположения файла CSS, независимо от пути любой страницы, которая загружает этот файл CSS. Поэтому, если ваши изображения в ~/Content/Images и ваши таблицы стилей в ~/Content/Stylesheets, вы всегда сможете использовать background-image: url(../Images/form_bg.gif);, и он будет работать независимо от местоположения страницы, на которой загружается таблица стилей.

Есть причина, по которой это не сработает?

5 голосов
/ 08 ноября 2008

Один прием, который я использовал в прошлом, заключался в том, чтобы на самом деле сделать мой 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 и заменит код на стороне сервера вашим относительным путем.

4 голосов
/ 27 октября 2008

Здесь некоторые ресурсы при реализации IHttpModule для перехвата веб-запросов к вашему приложению ...

Записать / адаптировать один для проверки на тип файла (например, псевдокод: если (запрос заканчивается ".css") ...)

затем используйте регулярное выражение для замены всех экземпляров "~ /" на System.Web.VirtualPathUtility.ToAbsolute ("~ /")

Я не знаю, как это повлияет на производительность, выполняя каждый запрос через этот вид фильтра, но вы, вероятно, можете возиться с вашим файлом web.config и / или вашими URL-адресами MVC, чтобы направлять все запросы .css через этот вид фильтра при пропуске его для других файлов.

Если подумать, вы, вероятно, можете добиться того же эффекта в приложении ASP.NET MVC, указав все ваши CSS-ссылки в специальном контроллере controller.action, который выполняет такую ​​предварительную обработку для вас. Я сомневаюсь, что это будет так же эффективно, как IHttpModule.

1 голос
/ 06 ноября 2008

Если вы пытаетесь проанализировать ~ / из любого файла, включая текстовые файлы, 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, то есть ...

Вы также можете использовать это, чтобы изменить любые типы файлов, чтобы вы могли назначить некоторые фильтры для изображений, некоторые для javascript или таблиц стилей или ... на самом деле что-нибудь ...

0 голосов
/ 28 октября 2008

Я создал класс утилит PathHelper, который дает мне все необходимые мне пути. Например

<link href="<%=PathHelper.CssUrl("FormulaIndex.css")%>" rel="Stylesheet" type="text/css"/>

Дает мне правильный полный URL-адрес с помощью System.Web.VirtualPathUtility.ToAbsolute () и моего собственного соглашения (content / css / yourFile.css).

Я сделал то же самое для js, xml, t9n, фото ... Он центральный, многоразового использования, и теперь мне нужно было всего лишь изменить одну строку, чтобы поймать перемещение папки «скрипты» из content / js в Scripts на всех моих сайтах и ​​страницах.

Идиотский ход, если вы спросите меня, но это реальность в текущей бета-версии: (

0 голосов
/ 27 октября 2008

Вы могли бы использовать URL Rewriter для исправления URL-адреса при поступлении запроса, хотя я не уверен, что в этом случае он выглядит так элегантно, как взлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...