Pergunta

No cenário WebForms normal, quaisquer URLs relativos à raiz (por exemplo ~ / pasta / file.txt) dentro CSS arquivos, tais como:

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

será automaticamente resolvido durante a execução se eu especificar

<head runat="server">

Na página de referência.

No entanto, isso não está acontecendo em um site ASP.NET MVC Beta 1.

Existe uma maneira que eu poderia habilitar essa funcionalidade sem recorrer a hacks ou arquivo CSS-loader? Como talvez HttpModules ou algo assim?

Ou estou não desigining meu site corretamente? O que é suposto ser um bom design?

Desde originais WebForms ASP.NET já tem esse recurso, eu prefiro utilizar qualquer funcionalidade existente, se possível. Mas eu não tenho muita idéia.

Esta aplicação web será implantado em vários ambientes onde a pasta raiz ~ pode não ser óbvio.


EDIT:. eu quero dizer a url no conteúdo do arquivo em si não url do arquivo

Foi útil?

Solução

Eu não me preocupei com o personagem ~ auto-encontrando-raiz. Eu entendo que você quer a mesma solução para o trabalho onde os difere do diretório raiz entre implementações, mas dentro do documento CSS você não deve ter quaisquer problemas usando caminhos relativos. Os caminhos no documento CSS (para o URL da imagem no seu exemplo) será sempre relativo ao local do arquivo CSS independentemente do caminho de qualquer página que carrega esse arquivo CSS. Então, se suas imagens estão em ~/Content/Images e suas folhas de estilo estão em ~/Content/Stylesheets, você sempre será capaz de usar background-image: url(../Images/form_bg.gif); e irá funcionar independentemente da localização da página que carrega a folha de estilo.

Existe uma razão pela qual isso não iria funcionar?

Outras dicas

Um truque que eu usei no passado, foi para realmente fazer o meu arquivo CSS tem uma extensão .aspx e definir a propriedade ContentType na assinatura página:

<%@ 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;
}

Isso irá garantir que o arquivo CSS atravessa o quadro ASP.NET, e substitui o código do lado do servidor com o caminho relativo.

Aqui são alguns recursos na implementação IHttpModule para pedidos de interceptação da web para a sua aplicação ...

Write / adaptar um para verificar se há filetype (por exemplo pseudocódigo: if (extremidades pedido com "Css") ...)

, em seguida, usar uma expressão regular para substituir todas as instâncias de "~ /" com System.Web.VirtualPathUtility.ToAbsolute ( "~ /")

Eu não sei o que isso vai fazer com o desempenho, correndo cada pedido através deste tipo de um filtro, mas provavelmente você pode mexer com o arquivo web.config e / ou suas rotas MVC URL para canalizar todas as solicitações .css através este tipo de filtro enquanto pular passado, para outros arquivos.

Venha para pensar sobre isso, você provavelmente pode conseguir o mesmo efeito dentro de um aplicativo ASP.NET MVC, apontando todos os seus refrences CSS em um controller.action especial que realiza este tipo de pré-processamento para você. eu duvido que seria tão alto desempenho como um IHttpModule embora.

Se você está tentando analisar o ~ / a partir de qualquer arquivo, incluindo arquivos de texto, javascript, etc, você pode escrever um manipulador que atribui um filtro para ele e você pode usar isso para procurar esses caminhos ... por exemplo ...

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));

    }

}

E você vai escrever um manipulador personalizado para saber quando atribuir este filtro ... como o seguinte ...

 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;

    }

}

Pode ter sido realmente mais fácil apenas para dizer "olhar para cima IHttpModules", mas este é um código que eu usei para arquivos de análise para fins diferentes ASP.NET Files caminhos.

Você também vai ter que mudar algumas coisas em suas configurações do IIS para permitir que os arquivos a serem analisados, definindo o ASP.net ISAPI para ser um curinga para todos os arquivos que são manipulados. Você pode ver mais neste website , se você estiver usando IIS6 que é ...

Você também pode usar isso para modificar quaisquer tipos de arquivos para que você possa atribuir alguns filtros para imagens, alguns para javascript ou folhas de estilo ou ... realmente qualquer coisa ...

Você poderia usar um URL Rewriter para corrigir o URL que o pedido vem, embora eu não estou tão certo de que é muito elegante como um hack neste caso.

Eu criei um PathHelper util classe que me dá todos os caminhos que eu preciso. Por exemplo

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

Dá-me o url completo correto com a ajuda de System.Web.VirtualPathUtility.ToAbsolute () e minha própria convenção (content / css / yourFile.css).

Eu fiz o mesmo para js, xml, t9n, fotos ... Sua central, reutilizável e agora eu só tive que mudar uma linha para capturar o movimento dos scripts pasta de conteúdo / js para Scripts em todos os meus sites e páginas.

Um movimento idiota se você me perguntar, mas é realidade no beta atual: (

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top