有或没有虚拟目录的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”适用于不在虚拟目录之上运行的应用程序。
用这个:
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:在引号之间抓取值