2013-01-04 16 views
7

Ich bin neu in MVC.MVC4 Bundles nach Hostname

Ich weiß, wie Pakete zu erstellen, ist es einfach, und es ist ein großartiges Feature:

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

Aber lassen Sie uns sagen, dass Ihre Anwendung unter verschiedenen Domains zugänglich ist und unterschiedliche Inhalte mit verschiedenen CSS je nach dem Hostnamen dient.

Wie kann ein Bundle verschiedene Dateien abhängig vom Hostnamen enthalten? In Anwendungsstart, wo meine RegisterBundles ist (wie in der MVC-Standard-Internet-Anwendung, mit der ich begann) Ich kenne noch nicht einmal den Host-Namen.

Was sind die besten Praktiken?

Wenn ich den Host-Namen bei der Registrierung der Bundles zur Verfügung hatte, konnte ich die richtige. CSS-Datei für den aktuellen Host-Namen auswählen. Kann ich beispielsweise Bundles auf Antragsbeginn-Anfrage registrieren und irgendwie prüfen, ob es bereits registriert war, und wenn nicht, die richtigen Dateien für den Host-Namen der Anfrage auswählen und registrieren?

Wenn ja, wie?

EDIT 1

In den letzten beiden Stunden, die ich dieses Thema ein wenig tiefer untersucht, lassen Sie mich meine Lösung mit Hoffnungen vorschlagen, die als mich mehr Experten mit MVC ist meine Methode, wenn falsch korrigieren.

I ersetzt:

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

mit:

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

Welche nur ein einfacher Helfer ist:

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

Wo RefreshBundleFor ist:

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

Und GetUpToSecondLevelDomain gibt gerade die Second-Level-Domain aus dem Hostnamen zurück, also GetUpToSecondLevelDomain ("www.foo.bar.com") = "bar.com".

Wie ist es?

Antwort

3

Übermäßig kompliziert - das Request-Objekt ist in Application_Start verfügbar. Verwenden Sie einfach:

var host = Request.Url.Host; 

bevor Sie Ihre Bundles registrieren und regulieren Sie Ihre Bundles Basis auf den zurückgegebenen Wert.

UPDATE registrieren alles, was Sie bündelt mit einem Domain-Schlüssel:

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

Dann wird in einem Basis-Controller, der alle Controller erben Sie den Paketnamen der Ansicht passieren bauen:

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

und dann im Layout oder in der Ansicht:

@Styles.Render(ViewBag.BundleName) 
+0

Aber ich vermute, es ist nicht genug. Application_Start wird nur aufgerufen, wenn die Anwendung gestartet wird, bedeutet mehrere Domänen in der gleichen Anwendung, dass es bei der ersten Anfrage von einer der Domäne, aber bei den nachfolgenden Anforderungen von den anderen Domänen gestartet wird? –

+0

Sie werden eine Tonne CPU-Zeit aufwenden und versuchen, bei jeder Anforderung zu bündeln und zu optimieren, mehr als wahrscheinlich verlangsamen Sie Ihre Reaktion und den Zweck der Bündelung/Minimierung zu besiegen. Sie sollten besser alle domänenspezifischen Bundles einmal bündeln/minimieren und dann mit dem Layout und/oder dem Controller das richtige Bundle auswählen. – viperguynaz

+0

Ich würde empfehlen, es im Layout zu tun, ein paar einfache if-Anweisungen und Sie sind fertig. Ich bin kein Fan von Logik in einem Layout, Ansicht usw., aber das ist eine gute Ausnahme. –