Für Webapplikationen, die mehrere "Mandanten" verwalten, ist es inzwischen üblich, diese "Instanzen" über die URL durch Subdomains zu unterscheiden, beispielsweise über kunde.applikation.domain. Dieser Post soll kurz zeigen, wie man die Sache mit ASP.NET MVC angehen könnte.
localhost
Um es vernünftig testen und lokal nutzen zu können, gibt es keinen (einfachen) Weg am lokalen IIS vorbei. Dieser muss also installiert und eingerichtet sein. Darüber hinaus muss die Windows-Hosts-Datei angepasst werden, mit deren Hilfe man das HTTP-Routing für das gesamte System manipulieren kann.
Die Datei befindet sich unter C:\Windows\System32\drivers\etc und trägt den schlichten Namen "hosts", ohne Dateiendung. Unter Vista und Windows 7 gilt zu beachten, dass der Editor zum Bearbeiten Administratoren-Rechte benötigt, sonst lässt sich die Datei nicht abspeichern.
In diese fügt man einfach ein paar Subdomains zum Testen ein:
1: 127.0.0.1 69.blubr.de
2: 127.0.0.1 test.blubr.de
3: 127.0.0.1 kunde.blubr.de
Zugriff auf die Subdomain
Führt man die Website nun unter einer dieser Domains aus und lässt sie sich aufrufen, hat der erste Schritt schon einmal geklappt. Jetzt muss man nur noch die Subdomain auslesen. Aber wo steht sie drin? Hierzu einfach mal in der Page-Direktive einer View das Attribut trace="true" setzen und die Seite aktualisieren. In den nun aufgelisteten Daten sieht man unter dem Punkt "Server Variables", dass sie sowohl in SERVER_NAME als auch HTTP_HOST ausgegeben wird.
Und wie greift man nun am einfachsten zu? Im Netz finden sich einige Ansätze, zum Beispiel auch der von Juliën Hanssens, der das einfach über das Routing löst, was mir aber nicht gefällt. Zum einen wird ja nichts geroutet, zum anderen wird so fast jede Controller-Action zwangsläufig schonmal mit einem Parameter belegt, da man "den Mandanten" ja fast überall braucht.
Interessanter finde ich hier eine Platzierung im vorhandene UrlHelper, welche sich über eine Extension Method relativ leicht realisieren lässt.
1: namespace MvcApplication2
2: {
3: public static class UrlExtensions
4: {
5: public static string Client(this UrlHelper url)
6: {
7: string client = (string) HttpContext.Current.Items["Client"];
8: if(client == null)
9: {
10: client = HttpContext.Current.Request.Headers["HOST"];
11: if (client.IndexOf(".") > -1)
12: client = client.Split('.')[0];
13: }
14: HttpContext.Current.Items["Client"] = client;
15: return client;
16: }
17: }
18: }
(Das Sample habe ich nicht test-driven entwickelt, sonst sähe es wohl noch etwas "aufgeblasener" aus, zwecks loserer Koppelung).
Damit der Zugriff von überall problemlos möglich ist, einfach den Namespace in der Web.config registrieren:
1: <pages>
2: <namespaces>
3: <add namespace="MvcApplication2" />
4: << span>namespaces>
5: << span>pages>
Und schon kann man sich überall den Mandanten ausgeben lassen, beispielsweise auch direkt in der View:
1: Mandant: <%= Url.Client() %>