Mi pregunta es similar a esta:
Excepto que quiero seguir con el paquete de MVC si puedo. Tengo un colapso cerebral al tratar de descubrir cuál es el patrón correcto para especificar paquetes de estilos tales como css independientes y conjuntos de imágenes como jQuery UI.
Tengo una estructura de sitio MVC típica con la /Content/css/
que contiene mi CSS base como styles.css
. Dentro de esa carpeta CSS también tengo subcarpetas como la /jquery-ui
que contiene su archivo CSS más una /images
carpeta. Las rutas de imagen en jQuery UI CSS son relativas a esa carpeta y no quiero meterme con ellas.
Según tengo entendido, cuando especifico un StyleBundle
Necesito especificar una ruta virtual que no coincide con una ruta de contenido real, porque (suponiendo que estoy ignorando las rutas al Contenido) IIS intentaría resolver esa ruta como un archivo físico. Entonces estoy especificando:
bundles.Add(new StyleBundle("~/Content/styles/jquery-ui")
.Include("~/Content/css/jquery-ui/*.css"));
renderizado usando:
@Styles.Render("~/Content/styles/jquery-ui")
Puedo ver la solicitud yendo a:
http://localhost/MySite/Content/styles/jquery-ui?v=nL_6HPFtzoqrts9nwrtjq0VQFYnhMjY5EopXsK8cxmg1
Esto está devolviendo la respuesta CSS correcta y minificada. Pero luego el navegador envía una solicitud de una imagen relativamente vinculada como:
http://localhost/MySite/Content/styles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
Que es un 404
.
Entiendo que la última parte de mi URL jquery-ui
es una URL sin extensión, un controlador para mi paquete, por lo que puedo ver por qué la solicitud relativa de la imagen es sencilla /styles/images/
.
Entonces mi pregunta es ¿cuál es la forma correcta de manejar esta situación?
fuente
Respuestas:
De acuerdo con este hilo en el paquete MVC4 css y las referencias de imagen , si define su paquete como:
Cuando defina el paquete en la misma ruta que los archivos de origen que formaron el paquete, las rutas de imagen relativas seguirán funcionando. La última parte de la ruta del paquete es realmente
file name
para ese paquete específico (es decir,/bundle
puede ser cualquier nombre que desee).Esto solo funcionará si está agrupando CSS desde la misma carpeta (lo que creo que tiene sentido desde una perspectiva de agrupación).
Actualizar
Según el comentario a continuación de @Hao Kung, alternativamente, esto ahora se puede lograr aplicando un
CssRewriteUrlTransformation
( Cambiar referencias de URL relativas a archivos CSS cuando se incluye ).NOTA: No he confirmado comentarios sobre problemas con la reescritura de rutas absolutas dentro de un directorio virtual, por lo que esto puede no funcionar para todos (?).
fuente
La solución Grinn / ThePirat funciona bien.
No me gustó que haya renovado el método Incluir en el paquete y que haya creado archivos temporales en el directorio de contenido. (terminaron siendo registrados, desplegados, ¡entonces el servicio no comenzó!)
Entonces, para seguir el diseño de Bundling, elegí realizar esencialmente el mismo código, pero en una implementación de IBundleTransform ::
Y luego envolvió esto en una Implementación de paquete:
Uso de muestra:
Aquí está mi método de extensión para RelativeFromAbsolutePath:
fuente
relativeToCSS
antes de llamarPath.GetFullPath()
.Mejor aún (en mi humilde opinión) implementar un paquete personalizado que corrige las rutas de la imagen. Escribí uno para mi aplicación.
...
Para usarlo, haz:
...en vez de...
Lo que hace es (cuando no está en modo de depuración) lo busca
url(<something>)
y lo reemplaza porurl(<absolute\path\to\something>)
. Escribí la cosa hace unos 10 segundos, por lo que podría necesitar un pequeño ajuste. He tenido en cuenta las URL totalmente calificadas y los DataURI base64 asegurándome de que no haya dos puntos (:) en la ruta de la URL. En nuestro entorno, las imágenes normalmente residen en la misma carpeta que sus archivos CSS, pero lo he probado con las carpetas principales (url(../someFile.png)
) y las carpetas secundarias (url(someFolder/someFile.png
).fuente
No es necesario especificar una transformación o tener rutas de subdirectorio locas. Después de mucha solución de problemas, lo aislé a esta regla "simple" (¿es un error?) ...
Si la ruta del paquete no comienza con la raíz relativa de los elementos que se incluyen, la raíz de la aplicación web no se tendrá en cuenta.
A mí me parece más un error, pero de todos modos así es como lo arreglas con la versión actual de .NET 4.51. Quizás las otras respuestas fueron necesarias en versiones anteriores de ASP.NET, no puedo decir que no tenga tiempo para probar retrospectivamente todo eso.
Para aclarar, aquí hay un ejemplo:
Tengo estos archivos ...
Luego configure el paquete como ...
Y hazlo como ...
Y obtenga el "comportamiento" (error), los propios archivos CSS tienen la raíz de la aplicación (por ejemplo, "http: // localhost: 1234 / MySite / Content / Site.css") pero la imagen CSS dentro de todo comienza "/ Contenido / Imágenes / ... "o" / Images / ... "dependiendo de si agrego la transformación o no.
Incluso intenté crear la carpeta "Bundles" para ver si tenía que ver con la ruta existente o no, pero eso no cambió nada. La solución al problema es realmente el requisito de que el nombre del paquete debe comenzar con la raíz de la ruta.
Lo que significa que este ejemplo se soluciona registrando y renderizando la ruta del paquete como ...
Entonces, por supuesto, podría decir que esto es RTFM, pero estoy bastante seguro de que yo y otros hemos elegido esta ruta "~ / Bundles / ..." de la plantilla predeterminada o en algún lugar de la documentación en el sitio web MSDN o ASP.NET, o simplemente me topé con él porque en realidad es un nombre bastante lógico para una ruta virtual y tiene sentido elegir tales rutas virtuales que no entren en conflicto con directorios reales.
De todos modos, así son las cosas. Microsoft no ve ningún error. No estoy de acuerdo con esto, o debería funcionar como se esperaba o se debería lanzar alguna excepción, o una anulación adicional para agregar la ruta del paquete que opta por incluir la raíz de la aplicación o no. No puedo imaginar por qué alguien no querría que se incluyera la raíz de la aplicación cuando hubiera una (normalmente, a menos que haya instalado su sitio web con un alias DNS / raíz del sitio web predeterminado). De hecho, ese debería ser el valor predeterminado de todos modos.
fuente
Descubrí que CssRewriteUrlTransform no se ejecuta si hace referencia a un
*.css
archivo y tiene el*.min.css
archivo asociado en la misma carpeta.Para solucionar esto, elimine el
*.min.css
archivo o haga referencia a él directamente en su paquete:Después de eso, sus URL se transformarán correctamente y sus imágenes se resolverán correctamente.
fuente
Tal vez soy parcial, pero me gusta mucho mi solución, ya que no hace ninguna transformación, expresiones regulares, etc. y tiene la menor cantidad de código :)
Esto funciona para un sitio alojado como un Directorio virtual en un sitio web de IIS y como un sitio web raíz en IIS
Así que creé una implementación de
IItemTransform
encapsuladoCssRewriteUrlTransform
y solíaVirtualPathUtility
arreglar la ruta y llamar al código existente:¿Parece funcionar bien para mi?
fuente
Aunque la respuesta de Chris Baxter ayuda con el problema original, no funciona en mi caso cuando la aplicación está alojada en un directorio virtual . Después de investigar las opciones, terminé con la solución de bricolaje.
ProperStyleBundle
La clase incluye código prestado del originalCssRewriteUrlTransform
para transformar adecuadamente las rutas relativas dentro del directorio virtual. También arroja si el archivo no existe y evita la reordenación de los archivos en el paquete (código tomado deBetterStyleBundle
).Úselo como
StyleBundle
:fuente
A partir de v1.1.0-alpha1 (paquete de lanzamiento previo), el marco utiliza el
VirtualPathProvider
para acceder a los archivos en lugar de tocar el sistema de archivos físico.El transformador actualizado se puede ver a continuación:
fuente
Aquí hay una Transformación de paquete que reemplazará las URL de CSS con URL relativas a ese archivo CSS. Simplemente agréguelo a su paquete y debería solucionar el problema.
fuente
cannot convert type from BundleFile to FileInfo
Otra opción sería utilizar el módulo de reescritura de URL de IIS para asignar la carpeta de imagen de paquete virtual a la carpeta de imagen física. A continuación se muestra un ejemplo de una regla de reescritura que podría usar para un paquete llamado "~ / bundles / yourpage / styles". .
Este enfoque crea un poco de sobrecarga adicional, pero le permite tener más control sobre los nombres de sus paquetes, y también reduce la cantidad de paquetes que puede tener que hacer referencia en una página. Por supuesto, si tiene que hacer referencia a múltiples archivos css de terceros que contienen referencias de ruta de imagen relativas, todavía no puede crear múltiples paquetes.
fuente
La solución de Grinn es genial.
Sin embargo, no funciona para mí cuando hay referencias relativas a la carpeta principal en la url. es decir
url('../../images/car.png')
Entonces, cambié ligeramente el
Include
método para resolver las rutas para cada coincidencia de expresiones regulares, permitiendo rutas relativas y también incrustar opcionalmente las imágenes en el CSS.También cambié IF DEBUG para verificar en
BundleTable.EnableOptimizations
lugar deHttpContext.Current.IsDebuggingEnabled
.Espero que ayude, saludos.
fuente
Simplemente puede agregar otro nivel de profundidad a su ruta de paquete virtual
Esta es una respuesta de muy baja tecnología y una especie de truco, pero funciona y no requerirá ningún procesamiento previo. Dada la extensión y complejidad de algunas de estas respuestas, prefiero hacerlo de esta manera.
fuente
Tuve este problema con los paquetes que tienen rutas incorrectas a las imágenes y
CssRewriteUrlTransform
no resuelven las rutas principales relativas..
correctamente (también hubo problemas con recursos externos como webfonts). Es por eso que escribí esta transformación personalizada (parece hacer todo lo anterior correctamente):Editar: no me di cuenta, pero usé algunos métodos de extensión personalizados en el código. El código fuente de esos es:
Por supuesto, debería ser posible reemplazarlo
String.StartsWith(char)
conString.StartsWith(string)
.fuente
m.Groups[2].Value.Count("..")
no funciona) YValue.StartsWith('/')
tampoco funciona porque StartsWith espera una cadena en lugar de un char.Después de una pequeña investigación, concluí lo siguiente: tiene 2 opciones:
ir con transformaciones. Paquete muy útil para esto: https://bundletransformer.codeplex.com/ necesita la siguiente transformación para cada paquete problemático:
Ventajas: de esta solución, puede nombrar su paquete como desee => puede combinar archivos css en un paquete desde diferentes directorios. Desventajas: necesita transformar cada paquete problemático
fuente
CssRewriteUrlTransform
arreglaron mi problemaSi su código aún no carga imágenes después de usarlo
CssRewriteUrlTransform
, cambie su nombre de archivo css de:A:
De alguna manera. (Puntos) no se reconocen en url.
fuente
Solo recuerde arreglar múltiples inclusiones CSS en un paquete como:
No puede simplemente agregar
new CssRewriteUrlTransform()
al final como puede hacerlo con un archivo CSS ya que el método no lo admite, por lo que debe usarInclude
varias veces :fuente