如何使用mvc 4中的bundle删除版本生成器的查询字符串标记

时间:2013-01-09 13:19:21

标签: asp.net-mvc-4 bundling-and-minification

您正在使用mvc4应用程序并使用bundle来呈现脚本和css

下面是我创建捆绑包的方式:

bundles.Add( new StyleBundle( "~/Content/css" ).Include(
                    "~/Content/bootstrap/css/bootstrap.css",
                    "~/Content/bootstrap/css/bootstrap-responsive.css",
                    "~/Content/site.css" ) );

现在它生成像我在浏览器源中看到的这样的包:

<link href="/Content/css?v=8HZAB6C8ZnrIPYNFzMQKt0AR4AUsUYBjxPPkbGSRIZo1" rel="stylesheet">

我想要的是删除链接中版本的“v”查询字符串。

由于

4 个答案:

答案 0 :(得分:6)

我已经为mvc-bundling创建了一个扩展,它允许你在URL中移动查询字符串部分。它可以像这样生成网址

/bundles/css/20130315191550.css

/捆绑/ CSS / _NNIf4XxdPCITzjlKPMgZwHMSUsPyxxGaNCIe6mgAkg1

http://github.com/unger/Bundling.Extensions

提供的代码

也许这可以让你对如何解决它有所了解?

答案 1 :(得分:4)

我最终做了以下事情:

首先,我使用此实现更改了默认BundleResolver

public class ReplaceQueryStringBundlerResolver : IBundleResolver
        {
            private readonly IBundleResolver _resolver;

            public ReplaceQueryStringBundlerResolver(IBundleResolver resolver)
            {
                _resolver = resolver;
            }

            public IEnumerable<string> GetBundleContents(string virtualPath)
            {
                return _resolver.GetBundleContents(virtualPath);
            }

            //The important part, modifies the generated Url
            public string GetBundleUrl(string virtualPath)
            {
                var bundleUrl = _resolver.GetBundleUrl(virtualPath);
                bundleUrl = bundleUrl.Replace("?v=", "/v/");
                return bundleUrl;
            }

            public bool IsBundleVirtualPath(string virtualPath)
            {
                return _resolver.IsBundleVirtualPath(virtualPath);
            }
        }

这可以在 RegisterBundles 方法中注册。

 BundleResolver.Current = new ReplaceQueryStringBundlerResolver(BundleResolver.Current);

这基本上指示当前解析器使用我们所需的 Url 格式。

此解决方案更好,因为我们不必在调用代码中的任何位置更改Styles.RenderScripts.Render个调用。

由于我们需要将这些新的捆绑Urls映射到捆绑表,我尝试使用当前的Api做类似的事情,但我无法使其工作,所以作为临时解决方案,我添加了重写web.config中的规则,以便我们可以将/v/重写为?v=。理想情况下,优化模块应该这样做,因为重写规则限制我们遵循一些命名约定,并且我的是所有捆绑虚拟路径应该以{{1​​}}开头

"~/bundles/"

如果我可以在处理捆绑请求的<rule name="RewriteBundlesWithNoQueryStrings" stopProcessing="true"> <match url="^bundles/(.*)/v/(.*)" /> <action type="Rewrite" url="/bundles/{R:1}?v={R:2}" /> </rule> <rule name="RewriteBundlesWithNoQueryStringsToDefault" stopProcessing="true"> <match url="^bundles/(.*)/(.*)" /> <action type="Rewrite" url="/bundles/{R:1}" /> </rule> 类中挂钩,我会提出更新。

答案 2 :(得分:2)

否,因为浏览器会缓存捆绑软件的陈旧版本,因为该查询字符串是内容更改时的指纹。

我们的待办事项中有一个项目可以自定义指纹在网址中的显示方式,但目前无法将其关闭。

一个简单的解决方法是显式地显示捆绑包的路径,因为如果您不想要查询字符串,则不会更改。

答案 3 :(得分:1)

Just write a simple extension like this:

public enum RenderType{Css, Js}
public static class _Extentions
{
    public static string RemoveQueryString(this IHtmlString _HtmlString, RenderType _RenderType){
        string Render = _HtmlString.ToHtmlString().Replace(Environment.NewLine, "").Replace("?v=", "/v/");
        Render = Render.Replace(_RenderType == RenderType.Css ? "\" rel=" : "\"></script>", _RenderType == RenderType.Css ? ".css\"  rel=" : ".js\"></script>");
        return Render;
    }      
}

And use url rewriting like this:

<rule name="rewrite css" enabled="true" stopProcessing="true">
<match url="^css/v/(.+).css"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false"/>
<action type="Rewrite" url="/css?v={R:1}"/>
</rule> 
<rule name="rewrite js" enabled="true" stopProcessing="true">
<match url="^js/v/(.+).js"/>
<conditions logicalGrouping="MatchAll" trackAllCaptures="false"/>
<action type="Rewrite" url="/js?v={R:1}"/>
</rule> 

and use it this way:

<%=Styles.Render("~/css").RemoveQueryString(RenderType.Css)%>
<%=Scripts.Render("~/js").RemoveQueryString(RenderType.Js)%>

Please note that the virtual path in the Render function and the one in the url rewriting must match:

Scripts.Render("~/js").RemoveQueryString(RenderType.Js)

match url="^js/v/(.+).js"