Das Vergrößern von virtuellen Festplatten mit VMware Fusion ist kein Problem - man gehe einfach in die Eigenschaften der jeweiligen virtuellen Maschine, wähle den Menüpunkt "Festplatten" und erhöhe die Festplattengröße auf den gewünschten Wert. Solang man bei der Erstellung der Disk keine feste Größe vorab zugewiesen wurde, klappt das problemlos - auch mehrfach.

Nachdem man seine VM nun bootet, wird das darin laufende Windows aber immer noch die alte Festplattengröße anzeigen. Das liegt daran, dass es von der Vergrößerungsaktion nichts mitbekommen hat. Aber auch kein Problem: Rechtsklick auf den Arbeitsplatz > Manage > Storage > Disk Management, Laufwerk auswählen und im Kontextmenü "Extend Volume..." klicken. Kurz bestätigen, fertig ist die vergrößerte Festplatte.

Eigentlich trivial, nur der letzte Punkt - den muss man eben kennen, daher kurz die Erwähnung (auch für mein Gedächtnis).

 

Dresden Neustadt 2010 - Blockadesong from antifaswingers on Vimeo.

 

 

Es sind die kleinen Dinge, die einen täglich aufhalten. Und so lang ich mich erinnern kann, waren es auch über die verschiedenen Generationen von ASP.NET hinweg auch immer wieder Themen rund um HTML-Checkboxen, die für Mehraufwand, Workarounds oder einfach nur graue Haare sorgten. Selbst im Jahr 8 von ASP.NET scheint sich das nicht geändert zu haben.

Worum geht es diesmal? Um den mit ASP.NET MVC 2 nun bald offiziell "neu" eingeführten Weg der Validierung über Attribute im View Model. Ähm was? Genau, also von vorn.

Bislang war eine der häufigsten (und bisweilen auch von mir verwendete) Vorgehensweise zum Validieren, dass jeder einzelne Wert aus dem Formular als Parameter der Controller-Methode übergeben und dann in dieser auf Herz und Nieren hin untersucht wurde.

Mit der neuen Version werden nun so genannte "DataAnnotations" eingeführt. Das heißt die Validierung erfolgt deklarativ über Attribute, die man den Properties seines View Models verpasst.

 1: public class FooViewModel
 2: {
 3:  [Required]
 4:  public string Text { get; set; }
 5: }

Durch das einfache Attribut [Required] lässt sich so sicherstellen, dass Text immer vom User angegeben werden muss, man spart sich also eine Menge Prüfungen und letztendlich auch (Unit-) Tests, also viel Tipparbeit. Eine ausführliche Einleitung, leider mit etwas veralteter Syntax, findet sich im Blog von Brad Wilson.

Aber natürlich gibt es auch hier Probleme, auf das erste bin ich gleich nach einer halben Stunde gestoßen, als ich etwas ganz übliches machen wollte: der User muss vor dem Abschicken eines Formulars eine Checkbox anhaken um sich mit den Allgemeinen Geschäftsbedingungen einverstanden zu erklären.

Mein View Model sah also wie folgt aus:

 1: public class SignUpViewModel
 2: {
 3:  [Required(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")]
 4:  [DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")]
 5:  public bool AgreesWithTerms { get; set; }
 6: }

Das dazu gehörige Formular in der View:

 1: <h1>Registrierung<h1>
 2:  
 3: <%= Html.ValidationSummary() %>
 4:  
 5: <% Html.BeginForm(); %>
 6:  
 7:  <fieldset>
 8:  <%= Html.CheckBoxFor(m => m.AgreesWithTerms) %>
 9:  <%= Html.LabelFor(m => m.AgreesWithTerms)%>
 10:  <br />
 11:  <input type="submit" value="Account erstellen" /> 
 12:  <fieldset>
 13:  
 14: <% Html.EndForm(); %>

Was passiert hier? Nichts. Nach kurzer Überlegung und etwas Suchen, ist auch schnell klar, warum. Ich zitiere Brad Wilson:

"The first problem is that [Required] on non-nullable properties doesn't quite behave like you'd expect. Literally, the implementation of the [Required] attribute is that the value cannot be null. Since a non-nullable value type can never be null, the [Required] attribute doesn't actually ever say the field is invalid.

So, what's it for, then? Failing to provide a value for a non-nullable property is actually a model binding error, as I mentioned above. We query the validation system and ask it for whatever it considers to be the "required" validator for the property, so we can determine what the message should be. The "required" validator is treated specially during model binding failures on non-nullable types, so that you're not stuck with the vanilla message 'A value is required.'

The off-shoot of this is that [Required] on a non-nullable value type cannot act as a guarantee that the form included a value. If it doesn't include a value, then model binding is skipped, which means the model binding failure won't occur. Additionally, when the [Required] validator is run, it queries the value from the model -- which will contain the value-types default value, typically 0 -- and say "that's not null, everything is all good here!".

If you make the property a nullable version of the value type, say by turning "int" into "int?", you'll be able to use [Required] as a way to ensure that a value is posted."

Der letzte Satz stimmt so leider in diesem Fall nicht. Macht man "AgreesWithTerms" aus dem Beispiel nullable, führt das unweigerlich zu folgender netten Exception bei der Ausführung:

"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions."

Was bleibt, ist ein eigenes Attribut zur Validierung. Glücklicherweise ist die komplette Architektur von ASP.NET MVC sehr offen, so dass man sich seine Erweiterungen beliebig selbst schreiben kann. In diesem Fall waren es nur ein paar Zeilen:

 1: public class BooleanRequiredToBeTrueAttribute : RequiredAttribute 
 2: {
 3:  public override bool IsValid(object value)
 4:  {
 5:  return value != null && (bool) value;
 6:  }
 7: }

Noch schnell die Deklaration geändert

 1: public class SignUpViewModel
 2: {
 3:  [BooleanRequiredToBeTrue(ErrorMessage = "Bitte lesen und akzeptieren Sie die AGB.")]
 4:  [DisplayName("Ich habe die AGB gelesen und akzeptiere diese.")]
 5:  public bool AgreesWithTerms { get; set; }
 6: }

Und siehe da: alles funktioniert wie es soll! Happy Coding :-)

 

Der Eurovision Song Contest ist ja für uns Deutsche so etwas wie ein nationales Trauma. Wir haben im Prinzip seit der Auflösung des Ostblocks keine Chance mehr ihn zu gewinnen, begegnen ihm aber doch jedes Jahr mit überzogener Erwartungshaltung aufs Neue. Und das selbst dann, wenn wir mal wieder völlig talentfreie Interpreten hinschicken, wie in den vergangenen 10 Jahren eigentlich immer. Allein Stefan Raab und Max Mutzke lieferten mit ihren Auftritten Anlass, die jeweiligen Niederlagen in Würde zu ertragen.

Das ist auch der ARD nicht entgangen, also hat sie in diesem Jahr ein Joint-Venture mit Raab geschlossen und ihne eine Show kreieren lassen, die zum Frontalangriff bläst: "Unser Star für Oslo". Nun gut, eine 0815-Castingshow mag man denken, aber Raab hat in den vergangenen Jahren bewiesen, dass er Plattformen für wirkliche Talente schaffen kann. Und das scheint ihm auch dieses Mal wieder zu gelingen, denn was dieses Mädel da gestern auf die Bühne gebracht hat, finde ich persönlich einfach nur: geil.

Leider geht der Auftritt nur bis 0:40 (danke Brainpool), hier gibt's die komplette Fassung inkl. bemerkenswerter Einschätzung der Jury.

Was macht nochmal Bohlen mit DSDS gerade?

 

Ich habe als Kind bzw. Jugendlicher Handball gespielt. Meist in irgendwelchen Turnhallen zur Uhrzeiten, in denen die Käffer, in denen wir waren, noch im Tiefschlaf waren. Zugeschaut haben, wenn überhaupt, meist nur Eltern. So eine Unterstützung hätte ich mir da auch mal gewünscht - auch wenn's ne andere Sportart ist.

Das ist übrigens die U11 von Lech Poznań aus Polen. Großartig! :-)

(via twitter)

 

Eine der grundlegenden Funktionen jeder Webanwendung mit Login ist die Möglichkeit, dem Nutzer bei der Anmeldung wieder auf die Sprünge zu helfen, wenn er sein Passwort vergessen haben sollte (und wenn der Login nicht über OpenID o.ä. erfolgt). Dafür gibt es verschiedene Strategien, von denen manche mehr, manche weniger benutzerfreundlich oder sicher sind.

Strategie 1: Vergessenes Passwort per E-Mail zusenden

Eine der häufigsten Varianten, dabei aber eine, die ich sofort ausschließen würde. Denn: um dem User das Passwort zusenden zu können, muss man es im Klartext gespeichert haben. Dafür gibt es aber außer diesem Punkt absolut keinen weiteren Grund, niemand benötigt Klartext-Passwörter. Eher im Gegenteil, sie stellen ein erhebliches Sicherheitsrisiko dar. Beispiele für geknackte Websites/Datenbanken mit tausenden geklauter Datensätze inkl. Passwort gibt es viele, und was passiert, wenn man, wie üblich, bei vielen Websites das gleiche oder nur leicht variierte Kennwort benutzt, und dieses jemandem in die Finger fällt, kann man sich selbst ausrechnen.

Strategie 2: Neues Passwort auf Anforderung generieren und per E-Mail zusenden

Sicher eine für den Benutzer bequeme und relativ sichere Variante. Problem: Das Passwort wird per Mail im Klartext durchs Netz geschickt und liegt dann auch im Posteingang, worauf schlimmstenfalls Dritte (später) zugreifen können. Man kann es allerdings natürlich nach dem Versand gehasht und somit sicher abspeichern. Problem Nummer zwei könnte eine Aktion eines Scherzkeks sein, der die eigenen Login-Daten verwendet und das System dazu bringt, ein neues Kennwort einzugeben, was für mich als Nutzer dann sehr nervig ist, da ich dieses Kennwort wieder ändern muss.

Strategie 3: "Aktivierungs-Key" erzeugen und per Mail zusenden

Diese Version nutze ich bisher in fast allen meinen Anwendungen. Auf Anforderung wird im Benutzerprofil ein "Aktivierungs-Key" hinterlegt, meist eine Guid, und diese dem Benutzer per E-Mail zugesendet. Dort kann er dann auf einen Link klicken bzw. den Key kopieren und gelangt anschließend auf eine Seite, in der er sich selbst ein neues Passwort vergeben und sich damit anschließend wieder einloggen kann.

Vorteile: das Passwort wird niemals unverschlüsselt und im Klartext durchs Netz geschickt, idealerweise ist die Zielseite zum Erzeugen des Kennworts SSL-gesichert. Außerdem hat der Account-Inhaber bei "Scherzanfragen" nichts weiter zu tun, als die Mail zu ignorieren oder zu löschen, denn sein Kennwort ändert sich ja erst durch sein aktives Handeln.

(Zwischen-) Fazit

Aus Perspektive der besten Sicherheit ist sicherlich die dritte Variante zu bevorzugen. Bequemer, sowohl für Nutzer als auch Entwickler (weil weniger zeitaufwendig), ist sicherlich die zweite Variante. Die Frage ist, ob man die Bequemlichkeit hier nicht ignorieren und den Aufwand in Kauf nehmen sollte, da es schließlich um die Sicherheit geht.

Was meint ihr?

 

Das oberpeinliche Rekrutierungs-Video des österreichischen Bundesheer ging heute durchs Netz:

Wer sich nun fragt, wie man auf so eine seltendämliche Idee kommen kann, dem sei gesagt: ganz einfach. Indem man sie einfach vom Nachbarn klaut. Was der Sache peinlichkeitstechnisch noch die Krone aufsetzt.

Welche Version nun beknackter ist, das ukrainische Original oder das österreichische Plagiat, dürft ihr selbst entscheiden.

 

Es ist da und es heißt wie erwartet: iPad. Apples neuestes Wundergerät in Form eines Tablet-Computers. Nach einer beispiellosen Marketingaktion, in der es dem Konzern aus Cupertino ausreichte hin und wieder gezielt ein paar Informationen nach außen tropfen zu lassen, selbst aber im Prinzip keinen Dollar für Werbung ausgeben zu müssen, hatte das seit Wochen, nein Monaten, mit Spannung erwartete Tablet nun heute seine Premiere.

Technisch sind die Fakten schnell aufgezählt: knapp 700g schwer, 10 Zoll groß, 16 bis 64 GB interner Speicher, 1024x768 Pixel Auflösung, W-LAN und wahlweise auch UMTS.

Was fehlt? Eine Kamera für Videotelefonie. Die Möglichkeit zu telefonieren. Die Möglichkeit den Akku auszutauschen. Die Möglichkeit den Speicher zu erweitern. Die Möglichkeit direkt per USB Geräte wie Kameras anzuschließen.

Dafür gibt es ein erweitertes iPhone OS mit der vom Telefon bekannten Oberfläche und ein paar speziell (und zugegeben sehr charmant) angepasste Anwendungen für die üblichen Aufgaben wie Kalender, Kontakte, Mail und Browsen. Dazu kommt die Möglichkeit sämtliche aus dem AppStore für iPhone und iPod Touch heute schon verfügbaren "Apps" zu nutzen und über einen neuen Book-Store auch Bücher zu kaufen.

Anwendungsgebiete gibt es trotz der Mängel zweifelsohne sehr viele. Sofern das Lesen wirklich gut funktioniert, kann man damit quasi überall Unmengen an Bücher mitnehmen ohne sie mitzuschleppen. Man kann Browsen, Videos und Musik genießen -wo immer man ist, egal ob im Zug, im Auto (als Beifahrer ;)) oder im Flugzeug. Und man kann in jeder geschäftlichen Präsentation oder Besprechung einen guten Eindruck hinterlassen, in dem man Dokumente mit einer geschickten Fingergeste hervorzaubert oder die neue Kundenwebsite damit präsentiert. Oder man bestimmt, was Apple TV auf dem heimischen TV abspielt, in dem man das iPad als interaktive Fernsehzeitschrift nutzt (in 20 Jahren wird dieser Begriff sicher nur noch albern sein). Oder man packt es ganz einfach in der Küche auf den Tresen, um ein gerade online heruntergeladenes Rezept auszuprobieren. Oder, oder, oder.

Ich denke deshalb, dass das iPad in vielen Lebenslagen passend sein und unser Verhalten im Umgang mit dem Internet noch einmal (r)evolutionieren kann. Erinnert sich noch jemand an Chrome OS? Man kombiniere Hardware und Software gedanklich miteinander und prompt schließt sich der Kreis. Es ist einfach etwas anderes, wenn man ein derartiges Device ins Leben integriert, als einen hässlichen, lärmenden oder auch nur unhandlichen PC, der zwei Minuten zum Booten braucht um sich danach ersteinmal die neuesten Virendefinitionen herunterzuladen.

Fazit aus argloser Kundensicht daher: So gut wie gekauft. Luft nach oben besteht natürlich enorm, siehe die eingangs aufgeführte Mängelliste. Aber schon jetzt hat das Gerät so viel Potential, dass ich neugierig genug bin, es auszuprobieren. Gerade auch bei den doch durchaus realistisch angesetzten Preisen.

Aber ...

Bauchschmerzen bleiben. Ich hatte zunächst erwartet, das Tablet mit Apples Snow Leopard zu sehen. Auf den Gedanken eines proprietären Systems à la iPhone OS bin ich bis vor ein paar Wochen gar nicht gekommen. Aber nun ist es Realität.

Man muss sich klar machen, dass man mit dem iPad nicht einfach einen Computer erhält, den man im Zweifelsfall wie gewohnt seinen eigenen Bedürfnissen anpassen kann, wie es selbst am Mac heute problemlos möglich ist. Genervt von Mac OS? Dann Bootcamp-Treiber genommen und Windows installiert. Keine Lust auf iCal, Apple Mail und iWorks? Dann einfach Microsoft Office oder OpenOffice.org installiert. Keinen Bock auf Safari? Wie wär's mit Firefox, Chrome oder Opera? Alles kein Problem - der offenen Plattform sei Dank.

Damit ist hier aber Schluss. Denn das auf dem iPad ausgelieferte System ist alles andere als offen - es ist so abgeschottet wie es beispielsweise Windows von Microsoft niemals gewesen ist.

Jede Anwendung, die man als Nutzer installieren möchte, muss vorher von Apple geprüft und in den Store geladen worden sein. Das macht es für den Anwender einerseits sehr einfach, weil er einen zentralen Anlaufpunkt für Anwendungen hat und sich keine Gedanken um Zahlungsmodalitäten oder die Installation machen muss. Selbst für den Entwickler ist es bisweilen angenehm, weil er mit seiner App Millionen potentieller Anwender direkt ansprechen kann und mit etwas Glück auch mit wirklich schwachsinnigen Apps tausende Euro verdient - ein Punkt, mit dem Apple übrigens auch ganz offensiv wirbt ("Eine neue Goldgrube für App-Entwickler").

Aber diese Medaille hat zwei Seiten, und die zweite ist verdammt dunkel. Wer sich etwas Zeit nimmt, wird im Netz hunderte von Storys über durch Apple abgelehnte Anwendungen finden. Mal mit nachvollziehbaren, oft mit nicht verständlichen Ablehnungsgründen. Denn, man muss sich das klar machen, Apple - und nur Apple - bestimmt, was Zugang zum iPhone, iPod oder nun iPad der Nutzer finden darf. Stört Apple etwas, wird es abgelehnt. Oft ist dies z.B. bei Anwendungen der Fall, die mehr oder weniger in direkter Konkurrenz zu Apple-eigenen Apps stehen, z.B. E-Mail-Clients oder Browser. Wie war das - Safari ist nix? Dann nehmen wir Opera Mobile? Forget it.

Aber nicht nur bei den Apps selbst findet man diese Probleme, auch bei elementaren Dingen wie der Unterstützung von Adobes Flash-Plugin für Websites mauert Apple bis heute. Es gibt faktisch keine Unterstützung auf dem iPhone, und wenn man der Keynote heute folgen darf, wird es diese auch nicht für das iPad geben. zumindest vorerst nicht, trotz der angeblich so tollen neuen CPU (Performance war eines der Hauptargumente Apples gegen Flash, man munkelt aber auch von einem eigenen Konkurrenzprodukt zu Flash (und Microsofts Silverlight) ...).

Unterm Strich ist das eine sehr gefährliche Entwicklung, die ich bei meinem iPhone noch bereit bin zu tolerieren, da dieses Gerät seit 1,5 Jahren ziemlich genau 99% meiner Anforderungen exakt erfüllt. Bei einem Computer sehe ich die Sache aber schon wieder anders. Da muss es auch gar nicht um DRM-Fesseln gehen. Allein die Tatsache, dass ich auf dem Gerät schlussendlich nicht selbst bestimmen kann, welche Apps ich installieren möchte, sondernd dass eine einzige Firma die Kombination aus Hard- und Software bestimmend unter ihren Fittichen hat, beunruhigt mich.

Das mag bei Insellösungen, die sich schlecht verkaufen noch egal sein. Aber was passiert, wenn Apple nun anfängt jedes Jahr 20 Millionen iPads zu verkaufen und wir irgendwann mehr Apfel-Tablets in unseren Haushalten haben als graue PCs?

Ich bin jedenfalls gespannt, wohin die Entwicklung geht ...

Anmerkung:

Es ist natürlich klar, dass Apple mit diesem Gerät, genau wie bei Smartphones, nun eine Vorreiterrolle einnehmen und den Markt befeuern wird. Es bleibt die Hoffnung, dass Konkurrenten nachziehen, wie es nun beispielsweise HP mit seinem Tablet samt Windows 7 angekündigt hat, eine Alternative die für mich durchaus attraktiv erscheint.

P.s.: ;-)

 

Am 13. Februar dieses Jahres haben sich in Dresden, wie jedes Jahr, Nazis zu einer der größten Demonstrationen zur Verbreitung ihres menschenfeindlichen Gedankenguts und zur Geschichtsverdrehung angekündigt. Im letzten Jahr liefen bereits 7.000 dieser merkbefreiten Irrlichter durch die Dresdener Innenstadt, gekontert von 10.000 Gegendemonstranten.

Dagegen regt sich Widerstand, der seitens vieler öffentlicher Personen, Organisationen und Parteien jeglicher Couleur getragen wird. Hauptanliegen der Aktion "Nazifrei! Dresden stellt sich quer" ist es, die Hoheit über die Straße durch die Faschisten auf friedlichem, gewaltfreien Weg zu verhindern.

Was tut unser Staat? Ich zitiere Hans-Christian Ströbele:

"Die sächsische Polizei und Justiz, welche kürzlich auch die Aufruf-Plakate in Dresden und Berlin beschlagnahmen ließ, wollen offenbar den Nazis die Straßen und Plätze Dresdens freiräumen für deren am 13. Februar geplanten braunen Aufmarsch."

Aber die Beschlagnahme der Plakate, die angeblich zu Gewalt aufrufen, ist nur ein Teil, der klar aufzeigt, welch geistig Kind da in den verantwortlichen Köpfen meines Heimatlandes zu finden ist. Das sächsiche Landeskriminalamt setzte auch alles daran, die Website, als zentrale Informationsplattform dienend, aus dem Netz zu bekommen. Der Text der Sperrandrohung findet sich im Beitrag bei netzpolitik.org freundlicherweise verlinkt.

Aber wie es sich für den zivilen Ungehorsam gehört, sind inzwischen eine Reihe von Spiegelungen online.

Dass es in mir brodelt, muss ich sicher nicht weiter ausführen. Dafür möchte ich euch alle aufrufen: "Spread the word!". Twittert, verlinkt die Site auf euren Blogs und Websites und zeigt, dass man den verf....en Nazis nicht die Straße, nicht das Wort und erst recht nicht die Deutung unserer Geschichte überlässt. Und wenn möglich: geht hin und demonstriert, friedlich und gewaltfrei!

Diese Verantwortung haben wir als Deutsche. Alle.

(Video gefunden bei Niklas)

 

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:    <namespaces>
   5:  <pages>

Und schon kann man sich überall den Mandanten ausgeben lassen, beispielsweise auch direkt in der View:

   1:  Mandant: <%= Url.Client() %>