有或没有虚拟目录的CssRewriteUrlTransform

我们正在使用MVC Bundling在我们的网站, CssRewriteUrlTransform确保图像的URL从dynamic捆绑CSS文件工作。

但是这只适用于不使用虚拟目录,即

http://localhost/VirttualDir不起作用,但http://localhost/ does。 这是因为重写URL时, CssRewriteUrlTransform转换不考虑虚拟文件夹。 所以如果一个图片的真实path是localhost/vdir/content/img/foo.png它会把它重写到localhost/content/img/foo.png这是错误的

我不确定要完全理解你的问题,但看到http://localhost在这里似乎是错误的。 你不应该使用你的包的绝对URL。

对于我来说CssRewriteUrlTransform完美的工作,这里是我如何使用它:

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

“捆绑”是虚拟的。

这有帮助吗?

更新

我对“VirtualDir”的事情感到困惑,因为你正在谈论IIS VirtualDir,而我正在考虑捆绑VirtualDir! 确实,在这种情况下,CssRewriteUrlTransform将重写URL到主机,而不是主机/虚拟目录URI。

要做到这一点,你必须派生CssRewriteUrlTransform,使其做你所需要的。 这里有一个很好的讨论: ASP.NET MVC4与Twitter Bootstrap绑定

似乎最好的答案是: 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); } } 

使用这个类而不是CssRewriteUrlTransform

“CssRewriteUrlTransform”适用于不在虚拟目录之上运行的应用程序。

所以,如果你的应用程序在http://your-site.com/上运行,它运行的很好,但是如果在http://your-site.com/your-app/上运行,你的所有图像都会有404,因为默认的“CssFixRewriteUrlTransform”是用“/”来引用你的图像。;

用这个:

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

注意:使用.min.css删除所有文件的css,因为如果不这样做,它不会修复。

我有同样的问题。 这是我如何解决它:

 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) + ")"); } } 

我知道这是远远不够完美,有很多边缘情况下,这可能会出错(我不知道你可以parsing一个正则expression式的CSS文件 – 首先 – 虽然这正是原来的CssRewriteUrlTransform做),但到目前为止它拥有…

我有问题,包含“数据”,甚至一个URL内的另一个url,所以我不得不重新做正则expression式,这是我的解决scheme:

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

基于RegEx:在引号之间抓取值

Interesting Posts