Автоматическое разрешение URL-адресов ASP.NET MVC в файлах CSS

StackOverflow https://stackoverflow.com/questions/240394

  •  04-07-2019
  •  | 
  •  

Вопрос

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

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

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

<head runat="server">

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

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

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

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

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

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


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

Это было полезно?

Решение

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

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

Другие советы

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

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

Напишите/адаптируйте его для проверки типа файла (например,псевдокод:if (запрос заканчивается на «.css») ...)

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

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

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

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

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

Я создал служебный класс 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 на всех моих веб-сайтах и ​​страницах.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top