c# - mvc - bundles asp net webforms
CssRewriteUrlTransform con o sin directorio virtual (4)
Estamos utilizando MVC Bundling en nuestro sitio, CssRewriteUrlTransform
se asegura de que las URL de imagen funcionen desde el archivo css de paquete dinámico.
Pero esto solo funciona cuando no se utiliza un directorio virtual, es decir,
http://localhost/VirttualDir
no funciona, pero http://localhost/
does. Esto se debe a que la CssRewriteUrlTransform
no tiene en cuenta la carpeta virtual al volver a escribir la url. Entonces, si una ruta real de imagen es localhost/vdir/content/img/foo.png
, la reescribirá a localhost/content/img/foo.png
cual es incorrecto
El ''CssRewriteUrlTransform'' funciona muy bien para aplicaciones que NO se ejecutan en la parte superior de un directorio virtual.
Por lo tanto, si su aplicación se ejecuta en http://your-site.com/ funciona muy bien, pero si se ejecuta en http://your-site.com/your-app/ tendrá 404 para todas sus imágenes, porque el valor predeterminado ''CssFixRewriteUrlTransform'' hace referencia a sus imágenes con ''/''.
Utilizar esta:
public class CssFixRewriteUrlTransform: IItemTransform {
private static string ConvertUrlsToAbsolute(string baseUrl, string content) {
if (string.IsNullOrWhiteSpace(content)) {
return content;
}
var regex = new Regex("url//([''/"]?(?<url>[^)]+?)[''/"]?//)");
return regex.Replace(content, match = > string.Concat("url(", RebaseUrlToAbsolute(baseUrl, match.Groups["url"].Value), ")"));
}
public string Process(string includedVirtualPath, string input) {
if (includedVirtualPath == null) {
throw new ArgumentNullException("includedVirtualPath");
}
var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
return ConvertUrlsToAbsolute(directory, input);
}
private static string RebaseUrlToAbsolute(string baseUrl, string url) {
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase)) {
return url;
}
if (!baseUrl.EndsWith("/", StringComparison.OrdinalIgnoreCase)) {
baseUrl = string.Concat(baseUrl, "/");
}
return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
}
}
Nota: borre todo el archivo css con .min.css, porque si no lo hace, no lo arregla.
No estoy seguro de entender completamente su problema, pero ver http://localhost
aquí parece incorrecto. Nunca debe usar una URL absoluta para sus paquetes.
Para mí CssRewriteUrlTransform funciona perfectamente, así es como lo uso:
bundles.Add(new StyleBundle("~/bundles/css").Include(
"~/Content/css/*.css", new CssRewriteUrlTransform()));
"Bundles" es virtual.
¿Esto ayuda?
Actualizar
Estaba confundido con el tema "VirtualDir", ya que estás hablando de IIS VirtualDir, ¡y estaba pensando en Bundle VirtualDir! Es cierto que en este caso CssRewriteUrlTransform reescribirá las URL en el Host, no en el URI Host / VirtualDir.
Para hacer eso, debe derivar CssRewriteUrlTransform para que haga lo que necesita. Aquí hay una buena discusión: ASP.NET MVC4 Bundling con Twitter Bootstrap
Parece que la mejor respuesta está allí: http://aspnetoptimization.codeplex.com/workitem/83
public class CssRewriteUrlTransformWrapper : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
}
}
Utilice esta clase en lugar de CssRewriteUrlTransform
Tengo problemas con la URL que contiene "datos" e incluso una url dentro de otra, así que tengo que volver a hacer la expresión regular, esta es mi solución:
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
{
throw new ArgumentNullException(nameof(includedVirtualPath));
}
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
var directory = VirtualPathUtility.GetDirectory(includedVirtualPath);
if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
{
directory += "/";
}
return new Regex(@"url/s*/(/s*([/'""]?)(?<scheme>(?:(?:data:)|(?:https?:))?)(?<url>(///1|.)*?)/1/s*/)")
.Replace(input, match => string.Concat(
"url(",
match.Groups[1].Value,
match.Groups["scheme"].Value,
match.Groups["scheme"].Value == "" ?
RebaseUrlToAbsolute(directory, match.Groups["url"].Value) :
match.Groups["url"].Value,
match.Groups[1].Value,
")"
));
}
private static string RebaseUrlToAbsolute(string baseUrl, string url)
{
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl)
|| url.StartsWith("/", StringComparison.OrdinalIgnoreCase))
{
return url;
}
return VirtualPathUtility.ToAbsolute(string.Concat(baseUrl, url));
}
}
basado en RegEx: agarrar valores entre comillas
Yo tuve el mismo problema. Así es como lo arreglé:
private class ProperUrlRewrite : IItemTransform
{
private static string RebaseUrlToAbsolute(string baseUrl, string url)
{
if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(baseUrl) || url.StartsWith("/", StringComparison.OrdinalIgnoreCase) || url.Contains('':''))
return url;
return VirtualPathUtility.Combine(baseUrl, url);
}
private static Regex UrlPattern = new Regex("url//s*//([''/"]?(?<url>[^)]+?)[''/"]?//)");
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath == null)
throw new ArgumentNullException("includedVirtualPath");
if (string.IsNullOrWhiteSpace(input))
return input;
string directory = VirtualPathUtility.GetDirectory(VirtualPathUtility.ToAbsolute(includedVirtualPath));
if (!directory.EndsWith("/", StringComparison.OrdinalIgnoreCase))
directory += "/";
return UrlPattern.Replace(input, match => "url(" + ProperUrlRewrite.RebaseUrlToAbsolute(directory, match.Groups["url"].Value) + ")");
}
}
Sé que está lejos de ser perfecto y hay muchos casos extremos en los que esto puede ir mal (no estoy seguro de que puedas analizar un archivo CSS con una expresión regular en primer lugar, aunque esto es exactamente lo que hace el CssRewriteUrlTransform
original), pero hasta ahora tiene ...