2013-05-10 51 views
1

我正在使用.Net MVC捆綁和縮小。它的工作就好了,除非你結束了類似下面的網址:.Net MVC捆綁/縮小 - CDN友好文件命名

/包/ AllMyScripts V = r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81

該項目將有靜態文件坐在AWS的Cloudfront,默認情況下它不不喜歡querystrings。它可以被改變來支持這一點,但是會有性能損失。

捆綁可以配置爲將令牌放入文件名而不是查詢字符串?我也願意使用Web Grease以外的東西。

+0

我可能不在,但我不確定與其他人有什麼關係? MVC捆綁將收集要捆綁的文件,捆綁它們並從Web服務器返回它們,而不是從實際的CDN返回。據我所知,你不能在你的網絡應用程序之外存儲這些軟件包(如果可以的話,那將會很棒,請糾正我)。如果你想讓你的壓縮文件在你的網頁應用程序之外,我想你需要手動壓縮你的項目。 – Tommy 2013-05-10 14:44:07

+0

@Tommy如果CDN沒有將其放入緩存中,則該CDN從源中拉取。一個請求http://cdn.mysite.com/content/css/min.css會去CDN,它不在那裏,CDN會從源請求 - 這是.net進入的地方。你不會推到CDN,它會從你身上拉開。 – ScottE 2013-05-10 14:53:44

+0

哦,我看到你現在問的是什麼,我正在相反的文件流向看你的問題。我的錯。我以爲你在問捆綁過程的實際拉動,而不是分配捆綁的CDN。 – Tommy 2013-05-10 14:56:06

回答

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

助手翻譯捆綁網址爲更CDN友好。例如:?

/內容/分鐘/ CSS V = 3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

變得

/內容/分鐘/ CSS/3GWBEyScjC610oPQm0JVybboQ_EmX3StAuCZjd_B7bE1

URL重寫(IIS URL重寫2.0)尋找一個(某些文件夾)並將其重寫爲content/min/{某個文件夾}?v = {某個標記}(默認路徑看起來如此)

因此,捆綁器是不明智的,路徑是來CDN友好。在我的情況下,我也會在網址的前面添加cdn url,但這不包括在上面。

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="/[email protected](System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/bundles/AllMyScripts").Replace("?v=","/"))"></script> 
+0

這是一個好主意,但必須有一個更有效的方式來做到這一點! – ScottE 2013-05-15 01:28:07

+0

@ScottE有效的方法是通過WG手動縮小腳本並將它們放在AWS CloudFront上,然後捆綁它們並將捆綁包的UseCdn屬性設置爲true。請參閱[Amazon CloudFront](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html),請參閱[捆綁和縮小]中的使用CDN(http://www.asp.net/) mvc/tutorials/mvc-4/bundling-and-minification) – 2013-05-15 05:28:12

+0

我更喜歡這個建議。你能否更詳細地解釋這個建議? – ScottE 2013-05-15 11:06:05

0

不知道如果我拿起你的後正常,但..

在BundelConfig中定義包時,有一個名爲CdnPath的ScriptBundle參數,可以爲每個Bundel設置CDN位置。

在RegisterBundles

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

bundles.UseCdn = True