.Net MVC捆绑/缩小 - CDN友好文件命名

时间:2013-05-10 13:47:21

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

我正在使用.Net MVC捆绑和缩小。它做得很好,除了你最终得到如下的网址:

/捆绑/ AllMyScripts?V = r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

项目将在AWS Cloudfront中放置静态文件,默认情况下它不像查询字符串。可以对其进行更改以支持此功能,但会降低性能。

可以将捆绑配置为将令牌放在文件名而不是查询字符串中吗?我也愿意使用Web Grease以外的东西。

3 个答案:

答案 0 :(得分:1)

好的,我提出了一个包含url重写和自定义html助手的合适解决方案。

的web.config:

  <rule name="BundlingRewrite" stopProcessing="true">
      <match url="^content/min/([^/]+)/([^/]+)/?$" />
      <conditions>
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="content/min/{R:1}?v={R:2}" />
  </rule>

助手:

public static IHtmlString RenderCdnCss(this HtmlHelper helper, params string[] paths)
{
    if (BundleTable.EnableOptimizations)
    {
        StringBuilder sb = new StringBuilder();
        Uri baseUri = helper.ViewContext.HttpContext.Request.Url;

        foreach (string s in paths) {
            Uri uri = new Uri(baseUri, BundleTable.Bundles.ResolveBundleUrl(s));
            sb.AppendFormat("<link href=\"{0}\" rel=\"stylesheet\"/>", uri.PathAndQuery.Replace("?v=", "/"));                    
        }
        return new HtmlString(sb.ToString());
    }
    return Styles.Render(paths);
}

帮助程序将捆绑的URL转换为更加CDN友好的内容。例如:

/ content / min / css?v = 3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

变为

/内容/分钟/ CSS / 3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

url rewrite(IIS Url Rewrite 2.0)在content / min / {some folder} / {some token}中查找url并将其重写为content / min / {some folder}?v = {some token}(默认路径看起来是什么)

所以,捆绑器并不是更明智的,并且路径变得对CDN友好。在我的情况下,我还会将cdn url添加到网址的前面,但上面没有包含。

答案 1 :(得分:0)

您可以使用MapRouteController将捆绑网址重写为CDN友好型。

而不是 /bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81您将拥有CDN_Bundle/bundles/AllMyScripts/r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

的RouteMap:

    routes.MapRoute(
            name: "CDN_Bundle",
            url: "CDN_Bundle/{*virtualPath}",
            defaults: new { controller = "CDN_Bundle", action = "Index" }

动作:

    public ActionResult Index(string virtualPath)
    {
        virtualPath = virtualPath.Trim('/');
        int lastSlash = virtualPath.LastIndexOf("/");
        string hashCode = virtualPath.Substring(lastSlash + 1, virtualPath.Length - lastSlash -1 );
        virtualPath = virtualPath.Substring(0, virtualPath.LastIndexOf("/"));

        WebClient webClient = new WebClient();
        webClient.Headers.Add("user-agent", Request.UserAgent);
        Stream data = webClient.OpenRead(Request.Url.GetLeftPart(UriPartial.Authority) + Path.Combine(Request.ApplicationPath, virtualPath) + "?v=" + hashCode);
        StreamReader reader = new StreamReader(data);
        string content = reader.ReadToEnd();

        return Content(content);
    }

并使用此代替Scripts.Render

         <script src="/cdn_bundle@(System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/AllMyScripts").Replace("?v=","/"))"></script>

答案 2 :(得分:0)

不确定我是否已经正确地拿起了你的东西但是......

当你在BundelConfig中定义bundle时,有一个名为CdnPath的ScriptBundle参数,可以为每个bundel设置一个CDN位置。

在RegisterBundles中

Dim bundel As New ScriptBundle("~/bundles/myfoo")
bundel.CdnPath = "http://foo.com/foo.js"

bundles.UseCdn = True