Pregunta

En el escenario normal de WebForms, cualquier URL relativa a la raíz (por ejemplo, ~ / folder / file.txt) dentro de archivos CSS como:

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

se resolverá automáticamente durante el tiempo de ejecución si especifico

<head runat="server">

En la página de referencia.

Sin embargo, eso ya no ocurre en un sitio web ASP.NET MVC Beta1.

¿Hay alguna forma en que pueda habilitar esta funcionalidad sin tener que recurrir a hacks o archivos de CSS-loader? Como tal vez HttpModules o algo así?

¿O no estoy desiglinando mi sitio web correctamente? ¿Qué se supone que es un buen diseño?

Dado que las Formas Web de ASP.NET originales ya tienen esta característica, prefiero utilizar cualquier funcionalidad existente si es posible. Pero no tengo mucha pista.

Esta aplicación web se implementará en varios entornos en los que la carpeta raíz no sea obvia.


EDITAR: Me refiero a la url en el CONTENIDO del archivo, no a la url del archivo en sí.

¿Fue útil?

Solución

No me molestaría con el carácter ~ de búsqueda de raíz automática. Entiendo que desea que la misma solución funcione cuando el directorio raíz difiere entre las implementaciones, pero dentro del documento CSS no debería tener ningún problema al usar rutas relativas. Las rutas en el documento CSS (a la URL de la imagen en su ejemplo) siempre serán relativas a la ubicación del archivo CSS, independientemente de la ruta de cualquier página que cargue ese archivo CSS. Entonces, si sus imágenes están en ~ / Content / Images y sus hojas de estilo están en ~ / Content / Stylesheets , siempre podrá usar background-image : url (../ Images / form_bg.gif); y funcionará independientemente de la ubicación de la página que carga la hoja de estilo.

¿Hay alguna razón para que esto no funcione?

Otros consejos

Un truco que usé en el pasado fue hacer que mi archivo CSS tenga una extensión .ASPX y establecer la propiedad ContentType en la firma de la 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;
}

Esto asegurará que el archivo CSS pase por el marco de ASP.NET y reemplace el código del lado del servidor con su ruta relativa.

Aquí are some resources en la implementación de IHttpModule a interceptar solicitudes web a su aplicación ...

Escriba / adapte uno para verificar el tipo de archivo (por ejemplo, pseudocódigo: si (la solicitud termina con " .css ") ...)

luego use una expresión regular para reemplazar todas las instancias de " ~ / " con System.Web.VirtualPathUtility.ToAbsolute (" ~ / ")

No sé qué hará esto con el rendimiento, ejecutando cada solicitud a través de este tipo de filtro, pero probablemente pueda jugar con su archivo web.config y / o su URL de MVC para canalizar todas las solicitudes .css a través de este tipo de filtro mientras se pasa por alto para otros archivos.

Ahora que lo pienso, es probable que pueda lograr el mismo efecto dentro de una aplicación MVC de ASP.NET apuntando todas sus referencias a CSS a un controlador especial. Acción que realiza este tipo de preprocesamiento para usted. aunque dudo que sea tan eficaz como un módulo IHttp.

Si está intentando analizar el ~ / de cualquier archivo, incluidos los archivos de texto, javascript, etc., puede escribir un controlador que le asigne un filtro y puede usarlo para busca esos caminos ... por ejemplo ...

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

    }

}

Y escribirá un controlador personalizado para saber cuándo asignar este filtro ... como el siguiente ...

 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;

    }

}

En realidad, podría haber sido más fácil decir "buscar IHttpModules" pero este es un código que he usado para analizar archivos en busca de rutas distintas a los archivos ASP.net.

También tendrá que cambiar algunas cosas en la configuración de IIS para permitir que se analicen los archivos configurando la ISAPI de ASP.net como un comodín para todos los archivos que se manejan. Puede ver más en este sitio web , si está utilizando IIS6, es ...

También puede usar esto para modificar cualquier tipo de archivo para poder asignar algunos filtros para imágenes, algunos para javascript o hojas de estilo o ... realmente cualquier cosa ...

Puede usar un Reescritura de URL para corregir la URL a medida que se recibe la solicitud, aunque No estoy tan seguro de que sea tan elegante como un truco en este caso.

Creé una clase de utilidad PathHelper que me da todas las rutas que necesito. Por ejemplo

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

Me da la url completa correcta con la ayuda de System.Web.VirtualPathUtility.ToAbsolute () y mi propia convención (content / css / yourFile.css).

Hice lo mismo para js, xml, t9n, fotos ... Es central, reutilizable y ahora solo tuve que cambiar una línea para capturar el movimiento de la carpeta de scripts de content / js a Scripts en todos mis sitios web y páginas.

Un movimiento estúpido si me preguntas, pero es la realidad en la versión beta actual :(

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top