Thomas goes .NET Wikipedia Affiliate Button

Schön, dass es nun neben den Passagieren augenscheinlich noch jemandem aufgefallen ist: die Regeln und Kontrollen zur Mitnahme von Flüssigkeiten ins Flugzeug sind völliger Schwachsinn.

"Ein Pilot, der sein Taschenmesser abgeben musste, marschierte wütend zu seinem Flugzeug, holte die Not-Axt aus dem Cockpit und knallte sie dem Sicherheitskontrolleur auf den Tisch."

Bei einem Flug dieses Jahr hatte meine Freundin ebenfalls "Flüssiges" im Gepäck, genau genommen drei winzige Fläschchen/Tuben Kosmetik (fragt mich nicht was) - die dann wohl die zulässige Höchstmenge überschritten. Also hielt ihr die Kontrolleurin die 3 - inhaltlich natürlich ungeprüft - vor die Nase und meinte, sie solle auswählen, was sie mitnehmen möchte, eins der drei musste da bleiben. Jede Wette: jeder Kriminelle entscheidet sich dann lieber dafür, seinen Sprengstoff dazulassen ...

 

Phil Haack fasst zusammen, was in Sachen ASP.NET in naher Zukunft passieren wird - bzw. was nicht. Lesenswert.

 

Wer nicht an Wunder glaubt, ist kein Realist
David Ben Gurion

Atomenergie ist wie ein Flugzeug ohne Landebahn
Jo Leinen

Zu letzterem passt ja fast zynisch die Meldung, dass die Amerikaner vor 40 Jahren eine Atombombe in Grönland verloren haben. Und sie bis heute nicht finden konnten.

 

ASP.NET MVC bringt in der Beta bereits einen Helper namens "ValidationSummary" mit, der eine ungeordnete Liste mit Fehlern darstellt, die sich über eine vordefinierte CSS-Klasse auch stylen lässt. Allerdings ist man dadurch nicht besonders flexibel was das Erscheinungsbild angeht, möchte man das Ganze mit abgerundeten Ecken darstellen, werden beispielsweise noch zwei äußere Container notwendig.

   1:  public static string CustomValidationSummary(this HtmlHelper html)
   2:  {
   3:      
   4:      if (html.ViewData.ModelState.IsValid)
   5:          return null;
   6:   
   7:      StringBuilder summary = new StringBuilder();
   8:   
   9:      summary.Append("<div class=\"CssErrorContainer630\">");
  10:      summary.Append("<div class=\"CssErrorContainer630Inline\">");
  11:      summary.Append("<ul>");
  12:   
  13:      foreach (var state in html.ViewData.ModelState)
  14:      {
  15:          foreach (var error in state.Value.Errors)
  16:          {
  17:              summary.AppendFormat("<li>{0}</li>", error.ErrorMessage);    
  18:          }
  19:      }
  20:   
  21:      summary.Append("</ul>");
  22:      summary.Append("</div>");
  23:      summary.Append("<div class=\"CssErrorContainer630Bottom\"></div>");
  24:      summary.Append("</div>");
  25:   
  26:      return summary.ToString();
  27:   
  28:  }

Das Ergebnis ist im Vergleich zum Standard-Summary (oben) im Screenshot schön zu sehen:

 

In Erinnerung an die als "Reichspogromnacht" in die Geschichte eingegangene Nacht von heute vor 70 Jahren.

70 Jahre - in Anbetracht unserer jahrtausende alten Geschichte ein Witz, quasi noch Gestern. Trotzdem erschreckt es mich immer wieder, wie der Abstand zu den Geschehnissen dazu immer größer wird und damit das Vergessen wächst. Das muss aber mit allen Mitteln verhindert werden, denn wir, alle Generationen der nach dem Krieg Geborenen, haben zwar keine Schuld an dem, was geschah, gleichwohl aber eine Verantwortung dafür, dass sich das nie wieder ereignet.

Update

Der 9. November ist für die Deutschen natürlich mehr als "nur" der Tag 1938. Auch 20 Jahre zuvor und 51 Jahre später ereignete sich im Nachgang Historisches. Dem letzten Ereignis verdanke ich es wohl, dass ich diesen Beitrag heute nun schreiben kann, und nicht auf einem 16-Bit-Robotron-Rechner in einer Art Sozialistischem-Extranet surfen muss! ;-)

Karsten hat die Ereignisse schön zusammengefasst:

 

Wer versucht über die Entwurfsansicht eine Tabelle in einer SQL-Server-2008-Datenbank zu ändern, erhält per default eine Fehlermeldung, die da lautet:

"Das Speichern von Änderungen ist nicht zulässig. Die vorgenommenen Änderungen erfordern das Löschen und Neuerstellen der folgenden Tabellen. Sie haben entweder Änderungen an einer Tabelle vorgenommen, die nicht neu erstellt werden kann, oder die Option 'Speichern von Änderungen verhindern, die die Neuerstellung der Tabelle erfordern' aktiviert."

Letzteres ist die Standardeinstellung - keine Ahnung warum. Ändern lässt sich das unter Optionen > Designers > Tabellen- und Datenbank-Designer. Einfach Haken raus und alles ist wieder gut.

 

Ergänzend zu meinem Post "ASP.NET MVC - Controller und Views in Areas aufteilen" seien hier noch zwei Ressourcen zum Thema genannt, die sich nachher aufgetan haben:

Danke Thomas für die Links.

Die Lösung von Phil Haack erscheint mir als wirklich brauchbar, ich denke ich werde sie einsetzen. Was mir insgesamt ein bisschen Bauchschmerzen bereitet, ist die Tatsache, dass das alles wirklich "beta" ist, und man zum heutigen Zeitpunkt nicht so richtig weiß, ob es mit dem Release oder nächsten Update noch kompatibel ist. Aber das ist halt das Leid des "Early Adopters" - ich muss ja auch unbedingt produktiv mit einer Beta arbeiten :-).

ASP.NET MVC hat sich aber inzwischen wirklich als schön schnell erwiesen, ich liebe die Arbeit damit inzwischen fast schon, vor allem weil es in vielen Bereichen einerseits "Back to the roots" bedeutet (mehr Kontrolle über den Output), andererseits trotzdem sehr schnelles Entwickeln von Ergebnissen zulässt, was im aktuellen Projekt wichtig ist, weil ich so schnell wie möglich einen brauchbaren Prototypen einer Website rauswerfen muss.

Meine erste Einschätzung dazu hat sich aber bisher trotzdem nicht als falsch herausgestellt. Ich denke in Projekten, die man quasi auf der grünen Wiese beginnen kann, und bei denen es sich um Websites handelt, kann man mit ASP.NET MVC wirklich schön arbeiten. Bei sehr formularlastigen Anwendungen aber würde ich aber immer noch auf WebForms zurückgreifen, da das Event-Modell samt Viewstate (ja, doch) einem das Leben an vielen Stellen eben doch auch erleichtern kann.

Die Situation, dass man nun als Entwickler bald beliebig wählen kann, was man verwendet, kann ich nur gutheißen.

 

Für mich eines der bedeutendsten Menschheitsprojekte dieser Zeit, daher ist es für mich keine Frage, da bei jedem Aufruf ein paar Euro zur Finanzierung beizutragen.

Wikipedia Affiliate Button

 

Oder so.

Ist gekauft. Ob ich's aber dieses Jahr noch lesen werde ... ich glaube nicht, dass ich dazu komme2. Lobos erstes Buch "Wir nennen es Arbeit" liegt auch noch halb gelesen im Regal. Btw.: Was macht denn zweimal das ß zwischen den Versalien? PFUI! Aber ansonsten sehr geile Vertriebsidee muss ich sagen. Bin ja auch drauf reingefallen ;-)

Gefunden bei Flo.

Update

2 Gerade die Amazon-Bewertungen gelesen. Kaufe ich mir doch nicht. Der Verweis auf das Video ist aber den Post trotzdem wert. Oder? ;-)

 

Ein nettes Feature von ASP.NET MVC ist das TempData-Dictionary. Damit kann man Dinge wie zum Beispiel Statusmeldungen temporär speichern und einmal abrufen - danach sind sie automatisch gelöscht.

Sinnvoll ist das zum Beispiel für Formulare, bei denen etwas gespeichert wird, und wo dem Benutzer nach erfolgreicher Speicherung eine Meldung ausgegeben werden soll. Dafür hat man grundsätzlich seit jeher und mal unabhängig von ASP.NET MVC zwei Möglichkeiten:

  1. Man gibt die Meldung nach Abarbeitung des (POST-) Requests direkt aus.
  2. Man erzeugt einen neuen Request durch eine Weiterleitung, entweder auf sich selbst oder auf eine Bestätigungsseite.

Der einfachste Weg ist schon immer der erste gewesen, gleichwohl er nicht der beste ist. Der Grund: die per POST gesendeten und ggf. erfolgreich gespeicherten Daten werden beim nächsten Aufruf durch den Client erneut gesendet. Aktualisiert der Benutzer z.B. nach "dem Speichern" die Seite in seinem Browser, erhält er zum einen eine blöde Frage, ob die Daten erneut gesendet werden sollen, zum anderen kann es dann bei schlechter Programmierung dazu kommen, dass einfach nochmal gespeichert wird. Ist der Nutzer nun gelangweilt oder anderweitig motiviert, kann er so einfach durch schlichtes F5/Enter in kürzester Zeit hunderte Datensätze speichern ...

Um das zu vermeiden bietet sich ebenfalls seit jeher der zweite Weg an. D.h. nach erfolgreicher Speicherung macht man einfach einen Redirect und zeigt dem Nutzer entsprechend die Erfolgsmeldung an. Mit ASP.NET MVC gibt's dafür grundsätzlich 2 Wege.

Man kann erstens auf eine andere View weiterleiten, also z.B.

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Create(string test)
   3:  {
   4:      // Speichern
   5:      // ...
   6:      return RedirectToAction("CreateSuccessfull");
   7:  }

Das macht Sinn, wenn der Prozess abgeschlossen ist, z.B. nach einer Benutzerregistrierung.

Man kann aber auch die gleiche View zurückliefern, was sinnvoll ist, wenn der Benutzer beispielsweise in der Lage sein soll, mehrere Datensätze nacheinander anzulegen. An diese View muss man nun irgendwie den Status übergeben, d.h. ihr mitteilen, dass der Datensatz bei der letzten Aktion erfolgreich erstellt wurde.

Üblicherweise macht man das z.B. mit ASP.NET WebForms entweder mit einem angehängten QueryString-Parameter oder einer "Session-Variable". Erstes sieht nicht schön aus, bei Zweitem muss man sicherstellen, dass der Session-Wert auch nur ein einziges Mal abgerufen und dann sicher gelöscht wird, will man keine ungewollten Seiteneffekte erzeugen.

Das MVC-Team von Microsoft hat hier mitgedacht und mit dem TempData-Dictionary eine Lösung geschaffen. TempData verwaltet seine Daten intern nämlich in einer Session und sorgt gleichzeitig dafür, dass ein Wert nach dem ersten und einzig möglichen Abruf auch sauber wieder gelöscht wird. Damit entfällt das manuelle Handling, was vorher nötig gewesen ist.

Der eleganteste Weg ist also der Redirect auf sich selbst und die Übergabe des Status via TempData:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Create(string test)
   3:  {
   4:      // Speichern
   5:      // ...
   6:      TempData["CreationSuccessfull"] = true;
   7:      return RedirectToAction("Create");
   8:  }

Dann kann man innerhalb der View ganz einfach eine nette Meldung ausgeben:

   1:  <% if(TempData["CreationSuccessfull"] != null) { %>
   2:   
   3:  <div style="background: green;">
   4:      Deine Einladung wurde erfolgreich verschickt.
   5:  div>
   6:   
   7:  <% } %>

Aktualisiert man nun die Seite, erhält man sie im Urzustand zurück - denn der Wert aus TempData wurde mit dem Aufruf bereits gelöscht. Im Ergebnis erzielt man damit eine gute "User Experience" und erhält obendrein wieder ein sauberes Formular ohne die Gefahr, dass der Benutzer ungewollt oder gewollt die Daten immer und immer wieder abschickt.