scripts mvc jqueryval bundleconfig bootstrap agregar css jquery-ui asp.net-mvc-4 bundle asp.net-optimization

css - jqueryval - MVC4 StyleBundle no resuelve imágenes



scripts render bundles jqueryval (15)

A partir de v1.1.0-alpha1 (paquete de prelanzamiento), 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:

public class StyleRelativePathTransform : IBundleTransform { public void Process(BundleContext context, BundleResponse response) { Regex pattern = new Regex(@"url/s*/(/s*([""'']?)([^:)]+)/1/s*/)", RegexOptions.IgnoreCase); response.Content = string.Empty; // open each of the files foreach (var file in response.Files) { using (var reader = new StreamReader(file.Open())) { var contents = reader.ReadToEnd(); // apply the RegEx to the file (to change relative paths) var matches = pattern.Matches(contents); if (matches.Count > 0) { var directoryPath = VirtualPathUtility.GetDirectory(file.VirtualPath); foreach (Match match in matches) { // this is a path that is relative to the CSS file var imageRelativePath = match.Groups[2].Value; // get the image virtual path var imageVirtualPath = VirtualPathUtility.Combine(directoryPath, imageRelativePath); // convert the image virtual path to absolute var quote = match.Groups[1].Value; var replace = String.Format("url({0}{1}{0})", quote, VirtualPathUtility.ToAbsolute(imageVirtualPath)); contents = contents.Replace(match.Groups[0].Value, replace); } } // copy the result into the response. response.Content = String.Format("{0}/r/n{1}", response.Content, contents); } } } }

Mi pregunta es similar a esta:

ASP.NET MVC 4 Minification e imágenes de fondo

Excepto que quiero seguir con el propio paquete de MVC si puedo. Estoy teniendo una falla cerebral al tratar de averiguar cuál es el patrón correcto para especificar paquetes de estilo, como el css independiente y conjuntos de imágenes como jQuery UI.

Tengo una estructura de sitio MVC típica con /Content/css/ que contiene mi CSS base como styles.css . Dentro de esa carpeta css también tengo subcarpetas como /jquery-ui que contiene su archivo CSS más una carpeta /images . Las rutas de imagen en el jQuery UI CSS son relativas a esa carpeta y no quiero meterme con ellas.

Como lo entiendo, cuando especifico un StyleBundle necesito especificar una ruta virtual que no coincida con una ruta de contenido real, porque (asumiendo que estoy ignorando las rutas hacia el Contenido), IIS intentará resolver esa ruta como un archivo físico. . Así que estoy especificando:

bundles.Add(new StyleBundle("~/Content/styles/jquery-ui") .Include("~/Content/css/jquery-ui/*.css"));

renderizado utilizando:

@Styles.Render("~/Content/styles/jquery-ui")

Puedo ver la solicitud saliendo 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, así que puedo ver por qué la solicitud relativa de la imagen es simplemente /styles/images/ .

Entonces mi pregunta es ¿cuál es la forma correcta de manejar esta situación?


Aquí hay una transformación de paquete que reemplazará las URL de css con las URL relacionadas con ese archivo css. Solo agrégalo a tu paquete y debería solucionar el problema.

public class CssUrlTransform: IBundleTransform { public void Process(BundleContext context, BundleResponse response) { Regex exp = new Regex(@"url/([^/)]+/)", RegexOptions.IgnoreCase | RegexOptions.Singleline); foreach (FileInfo css in response.Files) { string cssAppRelativePath = css.FullName.Replace(context.HttpContext.Request.PhysicalApplicationPath, context.HttpContext.Request.ApplicationPath).Replace(Path.DirectorySeparatorChar, ''/''); string cssDir = cssAppRelativePath.Substring(0, cssAppRelativePath.LastIndexOf(''/'')); response.Content = exp.Replace(response.Content, m => TransformUrl(m, cssDir)); } } private string TransformUrl(Match match, string cssDir) { string url = match.Value.Substring(4, match.Length - 5).Trim(''/''', ''"''); if (url.StartsWith("http://") || url.StartsWith("data:image")) return match.Value; if (!url.StartsWith("/")) url = string.Format("{0}/{1}", cssDir, url); return string.Format("url({0})", url); } }


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 clase ProperStyleBundle incluye código tomado de CssRewriteUrlTransform para transformar adecuadamente las rutas relativas dentro del directorio virtual. También se lanza si el archivo no existe e impide que se BetterStyleBundle a BetterStyleBundle archivos en el paquete (código tomado de BetterStyleBundle ).

using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Web; using System.Web.Optimization; using System.Linq; namespace MyNamespace { public class ProperStyleBundle : StyleBundle { public override IBundleOrderer Orderer { get { return new NonOrderingBundleOrderer(); } set { throw new Exception( "Unable to override Non-Ordered bundler" ); } } public ProperStyleBundle( string virtualPath ) : base( virtualPath ) {} public ProperStyleBundle( string virtualPath, string cdnPath ) : base( virtualPath, cdnPath ) {} public override Bundle Include( params string[] virtualPaths ) { foreach ( var virtualPath in virtualPaths ) { this.Include( virtualPath ); } return this; } public override Bundle Include( string virtualPath, params IItemTransform[] transforms ) { var realPath = System.Web.Hosting.HostingEnvironment.MapPath( virtualPath ); if( !File.Exists( realPath ) ) { throw new FileNotFoundException( "Virtual path not found: " + virtualPath ); } var trans = new List<IItemTransform>( transforms ).Union( new[] { new ProperCssRewriteUrlTransform( virtualPath ) } ).ToArray(); return base.Include( virtualPath, trans ); } // This provides files in the same order as they have been added. private class NonOrderingBundleOrderer : IBundleOrderer { public IEnumerable<BundleFile> OrderFiles( BundleContext context, IEnumerable<BundleFile> files ) { return files; } } private class ProperCssRewriteUrlTransform : IItemTransform { private readonly string _basePath; public ProperCssRewriteUrlTransform( string basePath ) { _basePath = basePath.EndsWith( "/" ) ? basePath : VirtualPathUtility.GetDirectory( basePath ); } public string Process( string includedVirtualPath, string input ) { if ( includedVirtualPath == null ) { throw new ArgumentNullException( "includedVirtualPath" ); } return ConvertUrlsToAbsolute( _basePath, input ); } private static string RebaseUrlToAbsolute( string baseUrl, string url ) { if ( string.IsNullOrWhiteSpace( url ) || string.IsNullOrWhiteSpace( baseUrl ) || url.StartsWith( "/", StringComparison.OrdinalIgnoreCase ) || url.StartsWith( "data:", StringComparison.OrdinalIgnoreCase ) ) { return url; } if ( !baseUrl.EndsWith( "/", StringComparison.OrdinalIgnoreCase ) ) { baseUrl = baseUrl + "/"; } return VirtualPathUtility.ToAbsolute( baseUrl + url ); } private static string ConvertUrlsToAbsolute( string baseUrl, string content ) { if ( string.IsNullOrWhiteSpace( content ) ) { return content; } return new Regex( "url//([''/"]?(?<url>[^)]+?)[''/"]?//)" ) .Replace( content, ( match => "url(" + RebaseUrlToAbsolute( baseUrl, match.Groups["url"].Value ) + ")" ) ); } } } }

Úsalo como StyleBundle :

bundles.Add( new ProperStyleBundle( "~/styles/ui" ) .Include( "~/Content/Themes/cm_default/style.css" ) .Include( "~/Content/themes/custom-theme/jquery-ui-1.8.23.custom.css" ) .Include( "~/Content/DataTables-1.9.4/media/css/jquery.dataTables.css" ) .Include( "~/Content/DataTables-1.9.4/extras/TableTools/media/css/TableTools.css" ) );


De acuerdo con este hilo en el paquete MVC4 css y las referencias de imagen , si define su paquete como:

bundles.Add(new StyleBundle("~/Content/css/jquery-ui/bundle") .Include("~/Content/css/jquery-ui/*.css"));

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 el 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

De acuerdo con el comentario a continuación de @Hao Kung, alternativamente, esto puede lograrse ahora aplicando una CssRewriteUrlTransformation ( Cambie las referencias de las URL relativas a los archivos CSS cuando se incluye ).

NOTA: No he confirmado los comentarios sobre problemas con la reescritura en rutas absolutas dentro de un directorio virtual, por lo que es posible que esto no funcione para todos (?).

bundles.Add(new StyleBundle("~/Content/css/jquery-ui/bundle") .Include("~/Content/css/jquery-ui/*.css", new CssRewriteUrlTransform()));


Descubrí que CssRewriteUrlTransform no se ejecuta si está haciendo referencia a un archivo *.min.css y tiene el archivo *.min.css asociado en la misma carpeta.

Para solucionar este problema, elimine el archivo *.min.css o *.min.css directamente en su paquete:

bundles.Add(new Bundle("~/bundles/bootstrap") .Include("~/Libs/bootstrap3/css/bootstrap.min.css", new CssRewriteUrlTransform()));

Después de eso, sus URL se transformarán correctamente y sus imágenes se resolverán correctamente.


La solución de Grinn / ThePirat funciona bien.

No me gustó que haya hecho una nueva versión del método Include en el paquete y que haya creado archivos temporales en el directorio de contenido. (terminaron siendo registrados, desplegados, ¡entonces el servicio no se iniciaría!)

Entonces, para seguir el diseño de Bundling, elegí realizar esencialmente el mismo código, pero en una implementación de IBundleTransform:

class StyleRelativePathTransform : IBundleTransform { public StyleRelativePathTransform() { } public void Process(BundleContext context, BundleResponse response) { response.Content = String.Empty; Regex pattern = new Regex(@"url/s*/(/s*([""'']?)([^:)]+)/1/s*/)", RegexOptions.IgnoreCase); // open each of the files foreach (FileInfo cssFileInfo in response.Files) { if (cssFileInfo.Exists) { // apply the RegEx to the file (to change relative paths) string contents = File.ReadAllText(cssFileInfo.FullName); MatchCollection matches = pattern.Matches(contents); // Ignore the file if no match if (matches.Count > 0) { string cssFilePath = cssFileInfo.DirectoryName; string cssVirtualPath = context.HttpContext.RelativeFromAbsolutePath(cssFilePath); foreach (Match match in matches) { // this is a path that is relative to the CSS file string relativeToCSS = match.Groups[2].Value; // combine the relative path to the cssAbsolute string absoluteToUrl = Path.GetFullPath(Path.Combine(cssFilePath, relativeToCSS)); // make this server relative string serverRelativeUrl = context.HttpContext.RelativeFromAbsolutePath(absoluteToUrl); string quote = match.Groups[1].Value; string replace = String.Format("url({0}{1}{0})", quote, serverRelativeUrl); contents = contents.Replace(match.Groups[0].Value, replace); } } // copy the result into the response. response.Content = String.Format("{0}/r/n{1}", response.Content, contents); } } } }

Y luego envuelto esto en una Implementación de paquete:

public class StyleImagePathBundle : Bundle { public StyleImagePathBundle(string virtualPath) : base(virtualPath) { base.Transforms.Add(new StyleRelativePathTransform()); base.Transforms.Add(new CssMinify()); } public StyleImagePathBundle(string virtualPath, string cdnPath) : base(virtualPath, cdnPath) { base.Transforms.Add(new StyleRelativePathTransform()); base.Transforms.Add(new CssMinify()); } }

Uso de la muestra:

static void RegisterBundles(BundleCollection bundles) { ... bundles.Add(new StyleImagePathBundle("~/bundles/Bootstrap") .Include( "~/Content/css/bootstrap.css", "~/Content/css/bootstrap-responsive.css", "~/Content/css/jquery.fancybox.css", "~/Content/css/style.css", "~/Content/css/error.css", "~/Content/validation.css" ));

Aquí está mi método de extensión para RelativeFromAbsolutePath:

public static string RelativeFromAbsolutePath(this HttpContextBase context, string path) { var request = context.Request; var applicationPath = request.PhysicalApplicationPath; var virtualDir = request.ApplicationPath; virtualDir = virtualDir == "/" ? virtualDir : (virtualDir + "/"); return path.Replace(applicationPath, virtualDir).Replace(@"/", "/"); }


La solución de Grinn es genial.

Sin embargo, no me funciona cuando hay referencias relativas a la carpeta principal en la url. es decir, url(''../../images/car.png'')

Por lo tanto, modifiqué ligeramente el método de Include para resolver las rutas para cada coincidencia de expresiones regulares, permitiendo las rutas relativas y también, opcionalmente, incrustar las imágenes en el css.

También cambié el IF DEBUG para verificar BundleTable.EnableOptimizations lugar de HttpContext.Current.IsDebuggingEnabled .

public new Bundle Include(params string[] virtualPaths) { if (!BundleTable.EnableOptimizations) { // Debugging. Bundling will not occur so act normal and no one gets hurt. base.Include(virtualPaths.ToArray()); return this; } var bundlePaths = new List<string>(); var server = HttpContext.Current.Server; var pattern = new Regex(@"url/s*/(/s*([""'']?)([^:)]+)/1/s*/)", RegexOptions.IgnoreCase); foreach (var path in virtualPaths) { var contents = File.ReadAllText(server.MapPath(path)); var matches = pattern.Matches(contents); // Ignore the file if no matches if (matches.Count == 0) { bundlePaths.Add(path); continue; } var bundlePath = (System.IO.Path.GetDirectoryName(path) ?? string.Empty).Replace(@"/", "/") + "/"; var bundleUrlPath = VirtualPathUtility.ToAbsolute(bundlePath); var bundleFilePath = string.Format("{0}{1}.bundle{2}", bundlePath, System.IO.Path.GetFileNameWithoutExtension(path), System.IO.Path.GetExtension(path)); // Transform the url (works with relative path to parent folder "../") contents = pattern.Replace(contents, m => { var relativeUrl = m.Groups[2].Value; var urlReplace = GetUrlReplace(bundleUrlPath, relativeUrl, server); return string.Format("url({0}{1}{0})", m.Groups[1].Value, urlReplace); }); File.WriteAllText(server.MapPath(bundleFilePath), contents); bundlePaths.Add(bundleFilePath); } base.Include(bundlePaths.ToArray()); return this; } private string GetUrlReplace(string bundleUrlPath, string relativeUrl, HttpServerUtility server) { // Return the absolute uri Uri baseUri = new Uri("http://dummy.org"); var absoluteUrl = new Uri(new Uri(baseUri, bundleUrlPath), relativeUrl).AbsolutePath; var localPath = server.MapPath(absoluteUrl); if (IsEmbedEnabled && File.Exists(localPath)) { var fi = new FileInfo(localPath); if (fi.Length < 0x4000) { // Embed the image in uri string contentType = GetContentType(fi.Extension); if (null != contentType) { var base64 = Convert.ToBase64String(File.ReadAllBytes(localPath)); // Return the serialized image return string.Format("data:{0};base64,{1}", contentType, base64); } } } // Return the absolute uri return absoluteUrl; }

Espero que ayude, saludos.


Mejor aún (IMHO) implementar un paquete personalizado que corrige las rutas de imagen. Escribí uno para mi aplicación.

using System; using System.Collections.Generic; using IO = System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Web; using System.Web.Optimization;

...

public class StyleImagePathBundle : Bundle { public StyleImagePathBundle(string virtualPath) : base(virtualPath, new IBundleTransform[1] { (IBundleTransform) new CssMinify() }) { } public StyleImagePathBundle(string virtualPath, string cdnPath) : base(virtualPath, cdnPath, new IBundleTransform[1] { (IBundleTransform) new CssMinify() }) { } public new Bundle Include(params string[] virtualPaths) { if (HttpContext.Current.IsDebuggingEnabled) { // Debugging. Bundling will not occur so act normal and no one gets hurt. base.Include(virtualPaths.ToArray()); return this; } // In production mode so CSS will be bundled. Correct image paths. var bundlePaths = new List<string>(); var svr = HttpContext.Current.Server; foreach (var path in virtualPaths) { var pattern = new Regex(@"url/s*/(/s*([""'']?)([^:)]+)/1/s*/)", RegexOptions.IgnoreCase); var contents = IO.File.ReadAllText(svr.MapPath(path)); if(!pattern.IsMatch(contents)) { bundlePaths.Add(path); continue; } var bundlePath = (IO.Path.GetDirectoryName(path) ?? string.Empty).Replace(@"/", "/") + "/"; var bundleUrlPath = VirtualPathUtility.ToAbsolute(bundlePath); var bundleFilePath = String.Format("{0}{1}.bundle{2}", bundlePath, IO.Path.GetFileNameWithoutExtension(path), IO.Path.GetExtension(path)); contents = pattern.Replace(contents, "url($1" + bundleUrlPath + "$2$1)"); IO.File.WriteAllText(svr.MapPath(bundleFilePath), contents); bundlePaths.Add(bundleFilePath); } base.Include(bundlePaths.ToArray()); return this; } }

Para usarlo, haz:

bundles.Add(new StyleImagePathBundle("~/bundles/css").Include( "~/This/Is/Some/Folder/Path/layout.css"));

...en lugar de...

bundles.Add(new StyleBundle("~/bundles/css").Include( "~/This/Is/Some/Folder/Path/layout.css"));

Lo que hace es (cuando no está en el modo de depuración) busca url(<something>) y lo reemplaza con url(<absolute/path/to/something>) . Lo escribí hace unos 10 segundos, así que podría necesitar un poco de ajuste. He tenido en cuenta las URL completas y las DataURIs de 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 ).


No es necesario especificar una transformación o tener rutas de subdirectorio locas. Después de muchos problemas, lo aislé a esta regla "simple" (¿es un error?) ...

Si la ruta de su paquete no comienza con la raíz relativa de los elementos que se incluyen, entonces la raíz de la aplicación web no se tendrá en cuenta.

Suena como un error más para mí, 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 las versiones anteriores de ASP.NET, no puedo decir que no haya tiempo para probar retrospectivamente todo eso.

Para aclarar, aquí hay un ejemplo:

Tengo estos archivos ...

~/Content/Images/Backgrounds/Some_Background_Tile.gif ~/Content/Site.css - references the background image relatively, i.e. background: url(''Images/...'')

Luego configura el paquete como ...

BundleTable.Add(new StyleBundle("~/Bundles/Styles").Include("~/Content/Site.css"));

Y hazlo como ...

@Styles.Render("~/Bundles/Styles")

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 de CSS está dentro de todo inicio "/ Content / Images / ... "o" / Images / ... "dependiendo de si agrego la transformación o no.

Incluso intenté crear la carpeta "Paquetes" 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.

El significado de este ejemplo se corrige al registrar y representar la ruta del paquete como ...

BundleTable.Add(new StyleBundle("~/Content/StylesBundle").Include("~/Content/Site.css")); ... @Styles.Render("~/Content/StylesBundle")

Así que, por supuesto, podría decir que esto es RTFM, pero estoy bastante seguro de que otros y yo recogimos esta ruta "~ / Bundles / ..." de la plantilla predeterminada o en algún lugar de la documentación en el sitio web de MSDN o ASP.NET, o Simplemente lo encontré porque en realidad es un nombre bastante lógico para una ruta virtual y tiene sentido elegir esas rutas virtuales que no entren en conflicto con directorios reales.

De todos modos, así es como es. Microsoft no ve ningún error. No estoy de acuerdo con esto, debería funcionar como se esperaba o debería lanzarse 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é nadie querría que se incluyera la raíz de la aplicación cuando había una (normalmente, a menos que haya instalado su sitio web con un alias DNS / raíz de sitio web predeterminada). Así que en realidad eso debería ser el predeterminado de todos modos.


Otra opción sería utilizar el módulo IIS URL Rewrite para asignar la carpeta de imágenes del paquete virtual a la carpeta de imágenes físicas. A continuación se muestra un ejemplo de una regla de reescritura que podría usar para un paquete llamado "~ / bundles / yourpage / styles"; tenga en cuenta las coincidencias de expresiones regulares en caracteres alfanuméricos, así como guiones, guiones bajos y puntos, que son comunes en los nombres de archivos de imagen .

<rewrite> <rules> <rule name="Bundle Images"> <match url="^bundles/yourpage/images/([a-zA-Z0-9/-_.]+)" /> <action type="Rewrite" url="Content/css/jquery-ui/images/{R:1}" /> </rule> </rules> </rewrite>

Este enfoque crea una pequeña sobrecarga adicional, pero le permite tener más control sobre los nombres de sus paquetes, y también reduce la cantidad de paquetes a los que debe hacer referencia en una página. Por supuesto, si tiene que hacer referencia a varios archivos css de terceros que contienen referencias de rutas de imagen relativas, aún no puede crear múltiples paquetes.


Simplemente puede agregar otro nivel de profundidad a la ruta de su paquete virtual

//Two levels deep bundle path so that paths are maintained after minification bundles.Add(new StyleBundle("~/Content/css/css").Include("~/Content/bootstrap/bootstrap.css", "~/Content/site.css"));

Esta es una respuesta súper baja en tecnología y una especie de pirateo, pero funciona y no requiere ningún procesamiento previo. Dada la longitud y la complejidad de algunas de estas respuestas, prefiero hacerlo de esta manera.


Tal vez estoy sesgado, pero me gusta mi solución, ya que no hace ninguna transformación, regex, 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 Implentation of IItemTransform encapsulado el CssRewriteUrlTransform y usé VirtualPathUtility para arreglar la ruta y llamar al código existente:

/// <summary> /// Is a wrapper class over CssRewriteUrlTransform to fix url''s in css files for sites on IIS within Virutal Directories /// and sites at the Root level /// </summary> public class CssUrlTransformWrapper : IItemTransform { private readonly CssRewriteUrlTransform _cssRewriteUrlTransform; public CssUrlTransformWrapper() { _cssRewriteUrlTransform = new CssRewriteUrlTransform(); } public string Process(string includedVirtualPath, string input) { return _cssRewriteUrlTransform.Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input); } } //App_Start.cs public static void Start() { BundleTable.Bundles.Add(new StyleBundle("~/bundles/fontawesome") .Include("~/content/font-awesome.css", new CssUrlTransformWrapper())); }

¿Parece funcionar bien para mi?


Tuve este problema con paquetes que tenían una ruta incorrecta a las imágenes y CssRewriteUrlTransform no resolvía las rutas principales relativas .. correctamente (también había un problema con recursos externos como webfonts). Es por eso que escribí esta transformación personalizada (parece hacer todo lo anterior correctamente):

public class CssRewriteUrlTransform2 : IItemTransform { public string Process(string includedVirtualPath, string input) { var pathParts = includedVirtualPath.Replace("~/", "/").Split(''/''); pathParts = pathParts.Take(pathParts.Count() - 1).ToArray(); return Regex.Replace ( input, @"(url/([''""]?)((?://??/./.)*)(.*?)([''""]?/))", m => { // Somehow assigning this to a variable is faster than directly returning the output var output = ( // Check if it''s an aboslute url or base64 m.Groups[3].Value.IndexOf('':'') == -1 ? ( m.Groups[1].Value + ( ( ( m.Groups[2].Value.Length > 0 || !m.Groups[3].Value.StartsWith(''/'') ) ) ? string.Join("/", pathParts.Take(pathParts.Count() - m.Groups[2].Value.Count(".."))) : "" ) + (!m.Groups[3].Value.StartsWith(''/'') ? "/" + m.Groups[3].Value : m.Groups[3].Value) + m.Groups[4].Value ) : m.Groups[0].Value ); return output; } ); } }

Edición: no me di cuenta, pero utilicé algunos métodos de extensión personalizados en el código. El código fuente de esos es:

/// <summary> /// Based on: http://.com/a/11773674 /// </summary> public static int Count(this string source, string substring) { int count = 0, n = 0; while ((n = source.IndexOf(substring, n, StringComparison.InvariantCulture)) != -1) { n += substring.Length; ++count; } return count; } public static bool StartsWith(this string source, char value) { if (source.Length == 0) { return false; } return source[0] == value; }

Por supuesto, debería ser posible reemplazar String.StartsWith(char) con String.StartsWith(string) .


CssRewriteUrlTransformarreglado mi problema
Si su código aún no carga imágenes después de usarlo CssRewriteUrlTransform, cambie el nombre de archivo css de:

.Include("~/Content/jquery/jquery-ui-1.10.3.custom.css", new CssRewriteUrlTransform())

A:

.Include("~/Content/jquery/jquery-ui.css", new CssRewriteUrlTransform())

De alguna manera (puntos) no se reconocen en url.


Después de una pequeña investigación, concluí lo siguiente: Tienes 2 opciones:

  1. Ir con las transformaciones. Paquete muy útil para esto: https://bundletransformer.codeplex.com/ necesita la siguiente transformación para cada paquete problemático:

    BundleResolver.Current = new CustomBundleResolver(); var cssTransformer = new StyleTransformer(); standardCssBundle.Transforms.Add(cssTransformer); bundles.Add(standardCssBundle);

Ventajas: de esta solución, puede nombrar su paquete como desee => puede combinar archivos css en un paquete de directorios diferentes. Desventajas: Necesitas transformar cada paquete problemático.

  1. Utilice la misma raíz relativa para el nombre del paquete, como donde se encuentra el archivo css. Ventajas: no hay necesidad de transformación. Desventajas: tiene una limitación en la combinación de hojas css de diferentes directorios en un solo paquete.