2013-01-04 88 views
7

我是MVC的新手。MVC4按主機名捆綁

我知道如何創建包,它很容易,這是一個很大的特點:

bundles.Add(new StyleBundle("~/content/css").Include(
    "~/content/main.css", 
    "~/content/footer.css", 
    "~/content/sprite.css" 
    )); 

但是,假設你的應用程序是在不同的域訪問和不同內容提供服務,依賴於主機名不同的CSS。

如何根據主機名稱獲得包含不同文件的包? 在應用程序的開始,我的RegisterBundles是(如在我開始的MVC標準互聯網應用程序中)我甚至不知道主機名。

什麼是最佳實踐?

如果我在註冊捆綁軟件時有可用的主機名,我可以爲當前主機名挑選正確的.css文件。 我是否可以在應用程序開始請求上註冊捆綁軟件包,並以某種方式檢查它是否已經註冊,如果沒有,請爲請求的主機名選擇正確的文件並註冊它?

如果是,如何?

編輯1

在最後兩個小時,我研究這個話題深入一點,讓我提出我的希望是誰比我更專業與MVC如果錯了可以糾正我的方法解決。

我代替:

@Styles.Render("~/Content/css") 

有:

@Html.DomainStyle("~/Content/css") 

這僅僅是一個簡單的輔助:

public static class HtmlExtensions 
{ 
    public static IHtmlString DomainStyle(this HtmlHelper helper, string p) 
    { 
    string np = mynamespace.BundleConfig.RefreshBundleFor(System.Web.Optimization.BundleTable.Bundles, "~/Content/css"); 

    if (!string.IsNullOrEmpty(np)) 
     return Styles.Render(np); 
    else 
    { 
     return Styles.Render(p); 
    } 
    } 
} 

其中RefreshBundleFor是:

public static string RefreshBundleFor(BundleCollection bundles, string p) 
{ 
    if (bundles.GetBundleFor(p) == null) 
    return null; 

    string domain = mynamespace.Utilities.RequestUtility.GetUpToSecondLevelDomain(HttpContext.Current.Request.Url); 

    string key = p + "." + domain; 

    if (bundles.GetBundleFor(key) == null) 
    { 
    StyleBundle nb = new StyleBundle(key); 

    Bundle b = bundles.GetBundleFor(p); 
    var bundleContext = new BundleContext(new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, p); 

    foreach (FileInfo file in b.EnumerateFiles(bundleContext)) 
    { 
     string nf = file.DirectoryName + "\\" + Path.GetFileNameWithoutExtension(file.Name) + "." + domain + file.Extension; 
     if (!File.Exists(nf)) 
     nf = file.FullName; 

     var basePath = HttpContext.Current.Server.MapPath("~/"); 
     if (nf.StartsWith(basePath)) 
     { 
     nb.Include("~/" + nf.Substring(basePath.Length)); 
     } 
    } 
    bundles.Add(nb); 
    } 

    return key; 
} 

而GetUpToSecondLevelDomain只是從主機名返回第二級域名,所以GetUpToSecondLevelDomain(「www.foo.bar.com」)=「bar.com」。

這是怎麼回事?

回答

3

過度複雜 - 請求對象在Application_Start中可用。只需使用:

var host = Request.Url.Host; 

在您註冊您的軟件包並根據返回的值有條件地註冊您的軟件包。

UPDATE 註冊所有你使用域密鑰束:

StyleBundle("~/content/foo1.css")... 
StyleBundle("~/content/foo2.css")... 

然後在鹼控制器,所有控制器繼承也可以構建包名稱傳遞給視圖:

var host = Request.Url.Host; // whatever code you need to extract the domain like Split('.')[1] 
ViewBag.BundleName = string.Format("~/content/{0}.css", host); 

然後在佈局或視圖中:

@Styles.Render(ViewBag.BundleName) 
+0

但我懷疑這還不夠。 Application_Start僅在應用程序啓動時調用,同一應用程序中的多個域意味着它從一個域的第一個請求開始,但是從其他域的後續請求開始? –

+0

您將耗費大量的CPU時間來嘗試捆綁和優化每個請求,這很可能會減慢響應速度並破壞捆綁/最小化的目的。您最好將捆綁/最小化所有特定於域的捆綁包一次,然後使用佈局和/或控制器來選擇合適的捆綁包。 – viperguynaz

+0

我會建議在佈局中做一些簡單的if語句,然後就完成了。我不是佈局,視圖等邏輯的粉絲,但這是一個很好的例外。 –