Schon lange angekündigt, nun ist es so weit: Das .NET Open Source CMS Umbraco ist in Version 5 verfügbar.
Seit Anfang Februar kann der Download Umbraco 5.0 CMS von Codeplex als Web Deployment und mit Sourcecode geladen werden.

Umbraco 5 wurde auf Basis von ASP.NET MVC neu geschrieben. Es handelt sich also um eine technisch ganz neue Version - so gesehen eine Version 1.0, jedoch - mit der gewohnten Funktionalität der (letzten) Version 4.7: “but it already has a tonne of features that we think make it a great CMS”. Für das Umbraco Team ein Meilenstein - und ebenso für alle ASP.NET Developer.
Einige Details und Performance-Test finden sich hier:
Umbraco 5.0 RTM is on CodePlex, ready for download
Umbraco 5 präsentiert sich optisch fast gleich wie Version 4.7 – ein eigener Artikel dazu folgt.
About liefert Version 5.0.0 RTM:

The future of Umbraco is here. 
In Single Page Applications verwendet man häufig Hash-Bang Urls (was das ist, hat Robert hier beschrieben).
Setzt man nun anstelle des üblichen HomeControllers, der die Startseite (üblicherweise die Index View) rendert, eine statische default.htm Datei ein, will man natürlich die Hash-Bang Urls möglichst elegant und wie z.B. von twitter gewohnt in diesem Stil darstellen:
http://meineseite/#!/machwas
Durch die Verwendung der default.htm mit aktiviertem Default-Controller, müßte man das ganze allerdings so darstellen:
http://meineseite/default.htm#!/machwas
Leider funktioniert
http://meineseite/#!/machwas
zunächst nicht mehr (es erscheint die Index-Seite des HomeControllers oder ein 404, falls man den HomeController bereits gelöscht hat).
Der Grund liegt in den Route-Definitionen, die per Default in der Global.asax.cs definiert sind, genauer in der Definition eines Default-Controllers:
Entfernt man die Definition des Default Controllers
funktioniert der Aufruf von
http://meineseite/#!/machwas
wie gewünscht.
Natürlich kann man auch die Index-View des HomeControllers als Startseite für eine Single Page Application verwenden, was ich persönlich aber nicht (mehr) mache.
Kostenloser Event – Scrum for Managers
Am 7. März 2012 (9:00-12:00), Microsoft Österreich GesmbH, Am Europlatz 3, 1120 Wien im Auditorium.
JETZT KOSTENLOS ANMELDEN ,
Agenda
| 08:30 – 9:00 | Registrierung |
| 09:00 – 10:15 | Scrum for Managers mit Mitch Lacey |
| 10:15 – 10:35 | Pause |
| 10:35 – 11:50 | Testen in agilen Projekten mit Christian Hassa |
Scrum for Managers (Mitch Lacey)
 | The role of the manager in a software company is changing. No longer is it about driving people to results, it is about enabling teams to be hyper-productive. How can this be accomplished? Scrum, an agile framework, has been used successfully to build hyper-productive teams. What is Scrum? How can a manager build hyper productive teams that outpace everyone? In this talk, you will hear from Mitch Lacey, former Microsoft program manager and his experiences helping teams adopt the Scrum framework. Through this, he noticed four patterns that were present in teams that succeeded and were absent in teams that failed. You will hear from a Certified Scrum Trainer exactly what Scrum is, its base components and the traits to help ensure success. Agenda: - Agile Principles and Values
- The Scrum Framework
- The Role of the Manager on a Scrum Team
- Getting Started with Scrum
Mitch is an agile practitioner and trainer who has been managing projects for over twelve years with numerous plan-driven and agile projects under his belt. As a Certified Scrum Trainer (CST), Mitch shares his experience through Certified ScrumMaster courses, Agile coaching engagements, conference presentations and his new book “The Scrum Field Guide: Practical Advice for Your First Year”. To find out more about Mitch, please visit www.mitchlacey.com. |
Testen in agilen Projekten (Christian Hassa)
 | Agile Projekte verursachen massive Probleme im klassischen Testvorgehen: Detailspezifikationen sind erst (wenn überhaupt) kurz vor der Implementierung verfügbar und der Test soll gleichzeitig mit der Entwicklung am Ende jeder Iteration abgeschlossen sein. Bei Iterationslängen von wenigen Wochen verursacht das beträchtlichen Mehraufwand für den Test, der sich noch dazu am Ende der Iteration konzentriert, wodurch das Ziel eines voll getesteten Systems am Ende jeder Iteration oft nicht erreicht werden kann. Testen ist ein kritischer Erfolgsfaktor für agile Projekte! Der Vortrag zeigt welche Änderungen notwendig sind, damit Test und Entwicklung effizient in agilen Projekten zusammenarbeiten, und jede Iteration ein getestetes System als Ergebnis liefert. Neben der Vorstellung von wichtigen Konzepten für agiles Testen (agile Testquadranten, Testautomatisierungspyramide und Specification-By-Example) zeigt der Vortrag auch, wie diese mit Visual Studio und dem Microsoft Toolstack praktisch implementiert werden können. Christian Hassa ist seit über 15 Jahren in der IT tätig. Als Geschäftsführer bei TechTalk verantwortet er dort sowohl technologische als auch methodische Ausrichtung. Sein langjähriges Spezialgebiet ist die Anforderungsanalyse und seit längerer Zeit deren Verknüpfung mit agilen Prinzipien und Scrum. Aktueller Schwerpunkt ist der Aufbau von „lebender Dokumentation“ für Softwaresysteme auf Basis von fachlich lesbarer Testautomatisierung. In diesem Zusammenhang beschäftigt er sich auch intensiv mit Behaviour Driven Development und ist Mitinitiator des Open Source Werkzeugs SpecFlow. |
Andreas Pollak
Product Marketing Manager Visual Studio & Expression

Pragmatischer Einkauf kann teuer sein! Spare bares Geld mit der richtigen Beratung für Visual Studio!! Unser persönliches Rückrufservice berät Dich gerne.
Je mehr ich mich in letzter Zeit mit den umfangreichen und spannenden Funktionen von HTML5 und CSS3 beschäftige, desto häufiger stelle ich mir die Frage:
Welcher Browser unterstützt eigentlich welche HTML5-Features?
Abhilfe schaffen u.a. zwei Suchmaschinen, die die HTML5- bzw. CSS3 Browserkompatibilität detailliert darstellen.
Eine rein technische Sicht der Dinge liefert hierbei die When can I use... Seite.
Über die Suchmaske kann nach HTML5-, CSS3- und SVG-Befehlen gesucht werden.

Wer noch zusätzlich ein paar Tipps & Tricks gezeigt haben möchte, findet bei dem Community Projekt HTML5 Please Rat:

Eine kleine Aufgabe: Jede neue Textzeile (Carriage Return/Wenn man Enter drückt
) in einer Textarea soll ein Element in einer Auflistung sein – wie mach ich das jetzt am einfachsten?
Eigentlich ein grundlegendes Element im Web und der Nutzer macht bewusst Absätze – daher wäre es nur gerecht, wenn man das auch entsprechend würdigt.
Kleine MVC Demo App:

Wir wollen die Eingaben in diesem Textfeld etwas näher analysieren. In meiner Variante geschieht das “splitten” auf der Server-Seite, allerdings wäre es über Javascript natürlich genauso möglich.
Nach dem OK Klick:
Der Controller nimmt den Eingabetext entgegen. Wenn der Nutzer [Enter] in der Textarea drückt, kommt als “Steuerzeichen” entweder ein \n oder \r\n mit (ich glaub das hängt mit den Betriebssystemen zusammen… lange Geschichte
)

Damit müssen wir den String nur noch bei diesen Zeichen splitten und schon können wir die einzelnen Absätze besonders behandeln:
public ActionResult Multiline(string input)
{
ViewBag.MultilineRaw = input;
List<string> eachLine = input.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
ViewBag.MultilineSplitted = eachLine;
return View("Index");
}
View:
@using(Html.BeginForm("Multiline", "Home"))
{
@Html.TextArea("input")
<button>OK</button>
}
@if(string.IsNullOrWhiteSpace(ViewBag.MultilineRaw) == false)
{
<h2>Input</h2>
<p>Raw: @ViewBag.MultilineRaw</p>
<h3>Each Line</h3>
<ul>
@foreach(var line in @ViewBag.MultilineSplitted)
{
<li>@line</li>
}
</ul>
}
Endergebnis:

Keine große Sache – aber vielleicht hilft es den einen oder anderen weiter.
[ Download auf Google Code ]
| Du willst mit Visual Studio Ultimate 2010 arbeiten, darfst aber nicht? Du weißt, dass Microsoft Visual Studio Ultimatemit MSDN das Nonplusultra für Entwickler, Tester, Entwicklungs- und Projektleiter ist. Aber Du arbeitest nicht damit, weil Dein Chef, Controller oder Budget-Verantwortlicher noch nicht vom Nutzen überzeugt ist? Wir liefern Dir jetzt die notwendigen kaufmännischen Argumente, damit Du auch Deinen Chef von den Vorteilen von Visual Studio 2010 überzeugen kannst. |  |
Andreas Pollak
Product Marketing Manager Visual Studio & Expression

Pragmatischer Einkauf kann teuer sein! Spare bares Geld mit der richtigen Beratung für Visual Studio!! Unser persönliches Rückrufservice berät Dich gerne.
In den nächsten Wochen möchte ich eine kleine Video-Reihe produzieren. Dabei werde ich auf verschiedene Aspekte rund um Cloud Computing und Windows Azure behandeln. Jedes Video soll dabei eine maximale Länge von 10 Minuten haben.
Und los geht’s mit einem ersten Video, in dem ich die Frage beantworte “Was ist Windows Azure?”. In knapp 10 Minuten erkläre ich darin, welche Dienste in Windows Azure vorhanden sind und wie sich die Ausführung eigener Cloud Services auf Azure gestaltet. Feedback natürlich willkommen.
Hier geht’s zum Video
Weitere Informationen
Auf Channel 9 wurde eine Kinect for Windows Quickstart Serie veröffentlicht:
SDK Download hier
This series includes everything you need to get started building applications using the Kinect for Windows SDK. You'll learn how to setup and configure the Kinect SDK using Visual Studio Express, how the Kinect color and depth camera work and how to use skeletal tracking to track joint positions in your application. You'll also learn how to use sound source localization to locate the direction of sound, how to use the Kinect to record audio, and how to use speech recognition to control your application via voice commands.

Write an App! - Sample Code / Open Source Projects
Kinect Service
A Windows Service so you can see Kinect data on your Windows Phone
Kinect Paint
Draw with your hands
Kinect Mouse Cursor
Control Windows with your hands
Coding4Fun Kinect Toolkit
Developer library for easy programming
Jellybean
Our famous drivable lounge chair code has been updated to the latest release of Kinect for Windows

id Software, die Macher von Doom, Quake, Wolfenstein & co., stellen regelmäßig ihre älteren Spieltitle als Open Source zur Verfügung. Das Ganze runterzuladen fand ich bisher immer recht mühselig, allerdings gibt es seit kurzer Zeit die Sourcen auch auf GitHub.
Darunter Spiele wie Doom 3, Quake 3, Wolfenstein für iOS. Wer also schon immer mal Interesse hatte in die Spielentwicklung reinzuschauen sollte mal ein Blick rein werfen.
Wie bereits vom Twitter Bootstrap Team angekündigt wurde offiziel die Version 2.0 des UI Toolskits “Twitter Bootstrap” veröffentlich.
Zudem wurden die Slides, welche bei der Release Party gezeigt wurden auch veröffentlicht:
Downloads finden sich auf der Twitter Bootstrap Seite auf GitHub.
Das Build System des TFS bietet die Möglichkeit einfach neue Parameter für den Build-Workflow
zu definieren.
In diesem Beispiel habe ich ein neues String-Argument mit dem Namen “ServerPath” hinzugefügt.
Dieses Argument können nun in der Build Definition eingestellt werden.
Etwas unschön ist noch, dass wir den Pfad als Text eingeben müssen, schöner wäre hier,
wenn wir den Pfad aus der Versionsverwaltung auswählen können. Man kann für die Attribute
einen Editor angeben und glücklicherweise gibt es für die Auswahl einer Datei oder
eines Pfades aus der Versionsverwaltung bereits einen entsprechenden Editor. Den wollen
wir nun einbinden. Dazu müssen wir die Metadaten konfigurieren.
Der Parameter Name muss hier genau dem Argument-Name entsprechen. Und nun kommt der
entscheidende Punkt, wir geben im Feld Editor “Microsoft.TeamFoundation.Build.Controls.ServerFileBrowserEditor,
Microsoft.TeamFoundation.Build.Controls” ein. Damit wird nun neben dem Eingabefeld
in der Build-Definition ein Button angezeigt mit dem sich der entsprechende Editor
öffnen lässt.
Thomas Trotzki, ein Kollege von mir, führt im Auftrag von Microsoft die C++ Days
durch. Es gibt noch vereinzelt Plätze. Wer also mit C++ arbeitet dem sei diese Veranstaltungsreihe
wärmstens empfolen.
C++ geht mit der Zeit – gehen Sie mit! Wir zeigen Ihnen die Neuerungen und Trends
in der Microsoft C++-Welt, von neuen Sprachfeatures über effektive Parallelisierung
bis hin zu professionellem Software Engineering durch Application Lifecycle Management.
Termine gibt es in Berlin, Bad Homburg, Karlsruhe oder Köln. Die Teilnahme ist natürlich
kostenlos, aber die Plätze sind begrenzt.
Zugegeben: In den letzten Jahren waren die Neuerungen rund um die „managed“ .Net-Programmierung
mit einschlägigen Sprachen wie C# im Fokus der Aufmerksamkeit. So ist .Net zu einer
der produktivsten Entwicklungsplattformen gewachsen.
Doch C++ ist zurück im Rampenlicht: Auch im 21. Jahrhundert wird C++ als Programmiersprache
nicht weg zu denken sein. In C++ können Sie stets selbst zwischen Performance und
Abstraktion wählen. Kein unnötiger Overhead, bei Bedarf volle Kontrolle. Und genau
das wird C++ auch in der Zukunft seinen Platz unter den Programmiersprachen sichern
– der Trend immer komplexere Anwendungen auf immer kleinere Hardware zu bringen unterstützt
dies nachhaltig.
Seit Visual Studio 6.0 hat sich auch in der Microsoft C++-Welt viel getan –also höchste
Zeit für ein Wissens-Update.
Wo? Wann?
2.2.2012 14:00- 18:00 Berlin: ANMELDUNG
7.2.2012 14:00- 18:00 Bad Homburg: ANMELDUNG
13.2.2012 14:00- 18:00 Karlsruhe: ANMELDUNG
5.3.2012 14:00- 18:00 Köln: ANMELDUNG
Teilnahme: Kostenlos
Der C++ Day 2012 wird freundlicherweise unterstützt von artiso.
Folgende Themen erwarten Sie:
C++ 11: Modernes C++ im 21. Jahrhundert
C++ bleibt aktuell – neue Sprachfeatures machen den nativen Klassiker fit für neue
Herausforderungen. Dieser Vortrag gibt Ihnen einen Überblick über die wesentlichsten
Neuerungen in C++ 11 – wie beispielsweise Smartpointer mit Reference-Counting (shared_ptr),
Lambda-Expressions, neue Container-Klassen, Iteratoren und Sprachkonstrukte wie for_each
sowie RValue References.
Parallel-Power in Visual Studio 11: Konzepte und Tools
Effektive parallele Programmierung erhöht die Performance in vielen Fällen drastisch,
braucht aber das richtige Know-How und spezialisierte Tools. Denn bei stetig steigender
Anzahl an Cores und CPUs wird es immer wichtiger, das Anwendungsmodell in Richtung
Skalierbarkeit hinsichtlich Multiprocessing auszulegen. Auch das Debugging bietet
einige Herausforderungen. Verschaffen Sie sich einen Überblick über die neuen Konzepte
rund um Parallelisierung in Windows API, Concurrency Runtime und Visual Studio.
Application Lifecycle Management für C++: Die nächste Generation
Application Lifecycle Management ist mittlerweile auch in der nativen Entwicklung
Pflicht: Mit Team Foundation Server haben Projektteams jeder Größe ein zentrales Portal
für Zusammenarbeit, Versionskontrolle, Work Item Tracking, Build-Management, Prozessunterstützung
und Fortschrittsreports . Dies ermöglicht den Mitgliedern von Teams, besser und effizienter
zusammenzuarbeiten. Der Haken bisher: Die wichtigsten Features wurden auch für C++
unterstützt, aber bestimmte interessante Features waren der .NET Welt vorbehalten.
Die gute Nachricht: Visual Studio 11 zieht hier nun nach – sehen Sie, welche Neuerungen
sie erwarten.
Der Referent

Thomas Trotzki ist ALM Consultant bei der artiso AG nahe Ulm und Microsoft-C++-Profi
der ersten Stunde.
Mit Microsoft C++ und den MFC beschäftigt er sich intensiv seit den ersten Beta-Versionen
zu Microsoft C/C++ 7.0, also bereits vor der Geburtsstunde von Visual C++ und Visual
Studio.
Technologisch ist er neben C++ und den MFC auch mit COM/DCOM und der gesamten „Managed
Welt“ vertraut und hat umfangreiche Expertise im Application Lifecycle Management.
Zurzeit betreut er Kunden bei der Einführung von Microsoft Team Foundation Server
und berät bei der Etablierung eines Application Lifecycle Management in deren Entwicklungsabteilungen. 
Zur Zeit bin ich an einer Weiterbildung für die Verwendung von .NET im Grossfirmenumfeld. Ein Thema darin ist ist Windows Communication Foundation (kurz WCF genannt).
Da ich aus der Ecke der Webprogrammierer komme interessiert es mit primär, wie ich einen WCF-Service von einer Webseite her ansprechen kann.
Was brauchen wir denn für einen Service der auf der Basis der WCF für einen Webseitenzugriff konfiguriert ist?
Vorbereitungen
- Erstellen eines neues ASP.NET Projektes über den Menüpunkt „Neues Projekt erstellen…“
- Mit NuGet zuerst die JQueryUI und dann die JQuery
Libraries hinzufügen
- Erstellen Sie einen Ordner Services in der Solution
- In den zuvor erstellten Service fügen Sie ein neues Item hinzu (Vorlage für einen
WCF-Service) und benennen Sie diesen mit „ImageService“
- Visual Studio erstellt uns eine .svc und ein entsprechendes Interface ImageService.cs.
Hier stehen noch nicht allzu viele Sachen drin sodass wir die DoWork Methode im
Interface ein wenig anpassen. Nach dem Hinzufügen des Service sollte die Solution
mit den aktuellen JQuery Referenzen ausgestattet sein und folgende .NET Dll’s als
Referenz aufweisen:
- System.Service.Model
- System.Runtime.Serializatin
WCF Konfiguration
Soweit so gut. Wir sind bereit den WCF Service zu implementieren. Hierzu wird in die Solution noch ein Verzeichnis Images hinzugefügt, dass einfach mit den Beispiel Bildern von Windows befüllt wird. Zuerst fangen wir mit der Konfiguration der Web.Config für unseren Dienst an.
Konfiguration der Web.Config mit dem „WCF Service Configurator“ (Finden Sie unter Tools bei Visual Studio 2010)
- Erstellen eines neuen Services
- Auswahl der DLL von welcher her der Service generiert werden soll. Sollte im bin
Verzeichnis keine DLL vorliegen so kann man dies mit dem „Erstellen der Solution“
beheben
- Den Vertrag (Contract) können wir stehen lassen und weiter klicken.

- Da wir einen ImageService für’s Internet bereitstellen wollen, lassen wir die Konfiguration
auf http sein.
- Auch weitere Optionen belassen wir auf dem Standard. Wir wollen einen einfachen
ImageService ohne Duplex Funktion und lassen den Vorschlag des Assistenten so wie
er ist.
- Zum Schluss erstellen wir die Endpunkt-Adresse über welche der Service erreicht
werden soll.
- Wir haben einen neuen Service erstellt, wie uns der Assistent nun mitteilt.
Anpassen des WCF Service für unsere Bedürfnisse
Nun haben wir den Service deklarativ in der Web.Config erstellt. Nun müssen wir noch Anpassungen vornehmen, damit der Service auch mit einer WebHttpBinding angesprochen werden kann (das Programmiermodell http von WCF).
Anpassen des erstellten Service für die Verwendung mit ASP.NET (WCF Service Configurator).
- Selektieren Sie den zuvor erstellten Endpunkt
- Das Binding muss mit der DropDownListe auf webHttpBinding gewechselt werden.
- Nun müssen wir dem Binding noch eine Konfiguration zuordnen. Dies können wir tun
indem wir den Punkt „Bindings“ auswählen und ein neues hinzufügen. ACHTUNG:
Man muss das WebHttpBinding auswählen, damit die erstellte Konfiguration darauf
wirkt.
- Wir geben der neu erstellen Konfiguration einen Namen und belassen die Standardwerte
so wie sie sind (Die Ausnahmen werden nachstehend aufgelistet).
|
Konfigurationselement
|
Wert
|
Grund
|
|
ByPassProxyOnLocal
|
True
|
Lokale Adressen werden nicht über einenProxy-Server aufgelöst.
|
|
CrossDomainScriptAccessEnabled
|
True
|
Zugriff von überall her möglich per Script (Internet Service).
|
- Nun wechseln wir wieder zu den Endpunkten und wählen unseren erstellten Endpunkt
aus. Danach können wir in der Bindungskonfiguration die neu erstellte Bindung auswählen.
Den WCF Service zum Leben erwecken
Wir erstellen uns eine Global.asax die für das Starten und Beenden der WebApplikationen die entsprechenden Methoden bereitstellt. Interessant sind die Methoden Application_Start und die Application_End.
- Wir fügen unserem Webprojekt eine Global.asax mit dem Befehl Add new Item… hinzu.
- Damit wir webHttp verwenden können müssten wir System.ServiceModel.Web referenzieren
damit wir ein Objekt vom Typ WebserviceHost erstellen können.
-
Die Global.asax sieht dann wie folgt aus:
using System; using System.ServiceModel.Web; using
Sample.WebHttpImageService.Services; namespace Sample.WebHttpImageService { public
class Global : System.Web.HttpApplication { ///
<summary>
/// Host is declared here to not been removed by
/// the carbage collector.
/// </summary>
private static WebServiceHost host = new WebServiceHost(typeof(ImageService), new
Uri("http://localhost:8099")); ///
<summary>
/// Occurs when application is staring up.
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void Application_Start(object sender, EventArgs e) { try { host.Open();
} catch (Exception exception) { host.Abort(); } } ///
<summary>
/// Occurs at application shutdown.
/// </summary>
///
<param name="sender"></param>
///
<param name="e"></param>
protected void Application_End(object sender, EventArgs e) { host.Close(); } } }
-
Startet man nun das Projekt kann unter Umständen die Fehlermedung kommen, dass man
eine nicht registrierte URL versucht aufzurufen. Abhilfe schafft hier das Visual
Studio als Administrator zu starten (generell mit WCF zu empfehlen).
-
Nun wollen wir prüfen ob der Service mit der Methode GetImages angesprochen werden
kann. Die machen wir indem wir http://localhost:8099/ImageService/GetImages in den
Browser eingeben. Wir eine Fehlermeldung, die besagt dass die Methode nicht ausgeführt
werden kann.
Ist ja eigentlich logisch, denn unsere momentane Service Methode erwartet einen
Parameter der über Web „GET“ übermittelt wird. Dies wurde noch nicht implementiert.
-
Ist das Attribut im Interface angegeben können wir zum Beispiel mit dem Auftruf
http://localhost:8099/ImageService/GetAllImages?path=Test einen Methodenaufruf machen
und erhalten das folgende Beispiel Resultat.
Anpassen der WCF Methode GetImages
Nun wollen wir doch, dass der Service über einen AJAX Aufruf per JQuery angesprochen werden kann. Hierzu gehen wir wie folgt vor. Da die Service-Methode noch nicht so tut wie wir das gerne wollen, dekorieren wir die Methode im Interface mit dem Attribute WebGet. Das Interface sieht nun wie folgt aus:
[ServiceContract]
public Interface IImageService{
[OperationContract]
[WebGet]
public List<string> GetImages(string path);
}
Die Implementierungsklasse sieht dann so aus:
public class ImageService : IImageService{
public List<string> GetImages(string path){
List<string> result = new List<string>(){ "Hello WCF"};
return result;
}
}
Clientseitige Implementierung
Nun kommen wir auf die Clientseite. Wir fügen, falls es nicht schon getan wurde, ein Default.aspx WebForms zur Solution hinzu.
Hierzu erstellen wir uns unter dem Verzeichnis (Scripts) ein Unterverzeichnis mit dem Namen „Custom“ und fügen uns dort eine ImageService.js Datei hinzu, die folgenden Inhalt aufweist. (Vergessen Sie nicht die JQuery Scriptreferenz im Header der Default.aspx hinzuzufügen).
Unser erstelltes Clientscript sieht dann so aus:
$(document).ready(function () {
var imagesUri = "http://localhost:7777/Images/";
jQuery.support.cors = true;
$.ajax({
type: "GET",
url: "http://localhost:8099/ImageService/GetImages?path=" + imagesUri,
dataType: "text",
contentType: "application/text; charset=utf-8",
success: function (message) {
//$('#Result').append(message);
var xmlDocument = jQuery.parseXML(message);
var images = xmlDocument.getElementsByTagName("string");
for (var index = 0; index <= images.length - 1; index++) {
$('#Result').append("<img src=\'" + images[index].textContent + "\' />");
}
},
error: function (message) {
}
});
});
Die Default.aspx braucht dann nur noch eine Script-Referenz auf diese Datei.
<head runat="server">
<title>Zugreifen auf WCF mittels JQuery</title>
<script type="text/javascript" language="javascript" src="Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript" language="javascript" src="Scripts/Custom/ImageService.js" ></script>
</head>
Der httpQuery muss mit dem Parameter der im Inteface für die Servicedefinition festgelegt worden ist übereinstimmen. Nun ist es nicht wirklich ansprechend ein Hallo reinzugeben und dann als Resultat Hallo WCF, mit den geschweiften Klammern zu erhalten.
Wichtig hierfür ist das JQuery für CrossDomain zugriff konfiguriert wird. Dies geschieht wie folgt:
jQuery.support.cors = true;
Nun da WCF und ASP.NET nicht im gleichen Kontext beheimatet sind kann die Grundlage beider genommen werden. Beide bauen auf System.Web.Hosting auf. Folgenes Beispiel lässt alle Bilder die vom Pfad übergeben worden sind mit dem DirectoryInfo suchen und finden.
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Hosting;
using System.Linq;
namespace Sample.WebHttpImageService.Services
{
/// <summary>
/// Get's the images from the path given by parameter.
/// </summary>
/// <param name="path">ImagePath to look for images.</param>
public class ImageService : IImageService
{
public string[] GetImages(string path)
{
List<string> result = new List<string>();
Uri uri = new Uri(path, UriKind.Absolute);
FileInfo[] images = new DirectoryInfo(HostingEnvironment.MapPath(uri.LocalPath)).GetFiles();
images.ToList().ForEach(image =>
{
string imageUrl = string.Format(@"{0}{1}", path, image.Name);
result.Add(imageUrl);
});
return result.ToArray();
}
Unser Image Service muss so dann nicht im ApsNetCompatibilityMode betrieben werden und wir können trotzdem auf Files auf dem WebServer zugreifen. Nähere Details können hier gefunden werden WCF Service and ASP.NET
Zu guter Letzt Verarbeiten wir Client-seitig das XML das wir vom Server zurück erhalten und zeigen die Bilder an.
Das Bilder anzeigen haben wir ja in die ImageService.js ausgelagert.
Fazit
Mit eigentlich ganz wenig Aufwand ist es möglich einen Service zur Verfügung zu stellen der von allen Interessierten konsumiert werden kann. Trickreich an den ganzen Recherchen war auf jeden Fall das Zusammenspiel zwischen ASP.NET und der WCF die ja nicht im gleichen Kontext laufen, ohne dass man das AspNetCompatibilityReruirement Attribut braucht, oder den WCF-Service im Kompatibilitätsmodus laufen lässt. Weiter werde ich versuchen in den nächsten Wochen ein wenig mehr um die Daten die ausgetauscht werden, zu beleuchten.
Wenn Ihnen dieser Artikel gefallen hat, würde ich mich über einen Kick freuen und bin auch empfänglich für Rückmeldungen und Kritik.

Bevor es so richtig mit Backbone.js los geht, möchte ich das neue Konzept von WPF-Blogger vorstellen, die grundlegenden Features beschreiben und über den generellen Aufbau als solchen berichten. Es sind zahlreiche Änderungen angedacht. Aus dem Feed-Aggregat soll eine Site mit weit mehr Benutzer-Interaktion entstehen. Einige Funktionalitäten stellen jedoch auch lediglich Überlegungen dar, die ich gerne zur Diskussion freigeben möchte. Aber mehr in dieser Vorstellung.
Status Quo
WPF-Blogger war ursprünglich als reines Feed-Aggregat konzipiert. Ziel war es, Feeds zum Thema WPF zu bündeln und Interessierten gesammelt zur Verfügung zu stellen. Folgende Features wurden in der ersten Version inkludiert:
- Feed-Aggregation von ausgesuchten Blog-Feeds
- Mehrsprachigkeit
- Registrierung von neuen Feeds
- Übersicht aller registrierten Feeds
- Archiv inklusive Suche
- Gesamtfeed und Sprachfeeds
- Statistiken
Umgesetzt wurde die Website mit ASP.NET und WebForms und ganz, ganz wenig JavaScript.

Feed-Aggregat
Für das Aggregieren der Feeds läuft ein eigener Job, der zeitgesteuert sämtliche Feeds hin auf Neuigkeiten prüft bzw. bereits importierte Artikel aktualisiert. Dieser bleibt durch die Neuentwicklung der Website unberührt, da alle wesentlichen Funktionen enthalten sind.
Quo vadis?
Das ursprüngliche “Konzept” war hauptsächlich auf mich persönlich zugeschnitten. Es sollte eine Stelle sein, an der ich alle interessanten Blogs zum Thema WPF sammeln kann. Da dies auch für andere von Interesse sein konnte, hatte ich mich damals kurzer Hand entschlossen, eine eigene Website online zu stellen.
Im Laufe der Zeit hat sich gezeigt, dass das Interesse für diese Site da ist, jedoch fehlt vielen (auch mir) die Möglichkeit selbst Informationen einzustellen bzw. gute Inhalte zu teilen - kennt man schließlich auch von anderen Webangeboten. So das Feedback.
Nun gut, aber wie sieht es um den geplanten Funktionen aus?
- Login über Drittanbieter. In der ersten Implementierungsphase wird Twitter implementiert. Als Erweiterung sollen Facebook und Google Plus ebenfalls angeboten werden, um möglichst wenige auszuschließen. Gewisse Funktionalitäten sind nur im eingeloggten Zustand möglich.
- Suche. Eine Suche war bis dato über das Archiv bereits möglich. Dies wird weiterhin möglich sein, soll aber präsenter platziert werden.
- Sprachauswahl. Wie bisher soll auch die Sprachauswahl weiter bestehen bleiben. Durch diese wird bestimmt, aus welcher Sprache Ergebnisse anzuzeigen sind. Die generelle Sprache der Website ergibt sich durch die Browsersprache.
- Sharing Content. Es soll möglich sein, einzelne Artikel über unterschiedliche Kanäle zu verteilen, um guten Content bestmöglich verteilen zu können. Angeboten sollen Twitter, Facebook und Google Plus werden. Zusätzlich soll es möglich sein, Artikel für das spätere Lesen zu markieren. Dies kann wahlweise in der Applikation selbst (man muss angemeldet sein) oder über die Anbindung von Drittanbietern (Read It Later etc.) geschehen.
- Statistiken. Diese sollen helfen, gute und interessante Inhalte schnell aufzufinden. Diese beziehen sich auf Topics, Autor und Aufrufen.
Nachfolgend findet sich ein Screen-Mock, der den Aufbau im ausgeloggten Zustand näher beschreibt.

Loggt sich der Benutzer ein, erhält er neue Möglichkeiten. Im ersten Schritt ist angedacht, ein Blog bzw. einen neuen Artikel einzustellen. Unter den Aktionen (rechts oben) können dann benutzerspezifische Einstellungen vorgenommen werden. Der Rest der Seite bleibt unverändert.

Allgemeine Verwendbarkeit
Eines der Ziele dieser Umsetzung ist, dass die entstehende Anwendung breiter eingesetzt werden kann. Sie soll den Grundstock für Feed-Aggregationen bieten, jedoch nicht auf diesen speziellen Anwendungsfall beschränkt bleiben.
Eingestellte Blogs und Artikel
Sämtlicher eingestellter Inhalt, der nicht aus einer vertrauenswürdigen Quelle stammt wird geprüft. D.h. ein neu eingestelltes Blog wird nicht automatisch aggregiert, sondern landet auf einer Liste von zu prüfenden Quellen. Damit soll zum Einen vermieden werden, dass Spam in der Auswahl landet, zum Anderen ist es durchaus sinnvoll, sich zuerst die Erlaubnis des Blogbetreibers einzuholen (wenn dies im Internet offensichtlich auch kaum üblich ist).
Neue eingestellte Artikel werden ebenfalls geprüft und freigeschalten. Auch hier soll es vermieden werden, dass Spam publiziert wird. Beiträge von Benutzern, die bereits 2 (oder eine andere zu konfigurierende Anzahl) freigeschaltete Artikel eingestellt haben, werden automatisch publiziert, da diese als vertrauenswürdig eingestuft werden. Dies kann über die Administration jederzeit rückgängig gemacht werden.
Administration
Die Administration soll im Wesentlichen folgende Funktionen bieten:
- Benutzerverwaltung
- Verwaltung der Blogs
- Verwaltung der eingestellten Beiträge (Beiträge via Blog-Feeds werden in dieser Liste nicht behandelt)
- Verfügbare Sprachen
- Diverse Einstellungen
Die Administrationsseite wird Benutzern mit entsprechender Rolle über die Aktionen angeboten.
Nichtziel
Es ist kein Ziel von WPF-Blogger, die gesamten Inhalte anzuzeigen. Der Autor soll honoriert werden. Aus diesem Grund werden auch weiterhin nicht die gesamten Beiträge angezeigt, sondern lediglich ein Teaser.
Offene Fragen / Feedback erwünscht
Es gibt meinerseits einige Überlegungen, die grundsätzlich gut zur Neuentwicklung von WPF-Blogger passen würden, bei denen ich mir allerdings nicht zu 100% sicher bin. Ich möchte sie an dieser Stelle zur Diskussion stellen, in der Hoffnung auf Feedback.
Bewertung
Von einschlägigen Seiten (siehe beispielsweise DotNetKicks oder der deutschsprachigen Umsetzung) ist man es gewohnt, Beiträge bewerten zu können, um so die Spreu vom Weizen zu trennen. Das ist grundsätzlich eine gute Sache. Im Endeffekt ist mein Ansatz aber der Aktualität gewidmet. Der Benutzer soll einen schnellen Überblick erlangen, was sich in den abgedeckten Bereichen tut. Nichts desto trotz sollte er - meiner Meinung nach - doch auch eine Rückmeldung erhalten, welcher Inhalt von anderen empfohlen wird. Anstatt einer direkten Bewertung kann dies aber auch durch die eigentliche Statistik-Auswertung geschehen. Links, die häufig geklickt werden, scheinen grundlegend interessanter zu sein, als solche mit wenigen Aufrufen. Daraus könnte eine Bewertung abgeleitet werden, ohne den Benutzer zu einer Bewertung zu nötigen.
Kommentare
Wünschenswert wäre eine Möglichkeit Kommentare zu hinterlassen. Die Ideallösung wäre, dass sämtliche Kommentare an das eigentliche Blog zurückfließen und dem Verfasser des Artikels zu Gute kommen. Allerdings habe ich hierfür noch keine zufriedenstellende Lösung gefunden, wodurch ich die gesamte Funktionalität in Frage stelle. Meinungen?
Ausblick
Der nächste Artikel der Serie über Backbone.js beschäftigt sich mit dem Thema der Suchmaschinen. Darin wird hinterfragt, für welche Teile der Website der Einsatz von Backbone.js tatsächlich geeignet ist. Soll heißen, welche Inhalte werden statisch ausgeliefert und welche erst durch den Client erstellt.
Der TFS bzw. der MTM unterstützen leider keine Versionierung von Test Cases. Wenn
man nun für unterschiedliche Versionen einer Software Test Cases verwalten möchte,
muss man die Test Cases kopieren. Wie damit die Versionierung von Test Cases abgebildet
werden kann, habe ich hier beschrieben.
Um das Kopieren größerer Mengen von Test Cases zu vereinfachen, gibt es nun das Test
Case Copy Tool von Anna Russo.
http://www.improvingsoftwarequality.com/2012/01/new-version-of-bulk-copy-test-cases.html
Microsoft Exchange Online auf dem Smartphone genießen können ab sofort auch Nutzer eines BlackBerry®-Gerätes: Dank der von BlackBerry-Hersteller Research in Motion (RIM) gehosteten Business Cloud Services für Microsoft Office 365, die nach mehrmonatiger öffentlicher Betaphase jetzt offiziell freigegeben wurden, profitieren BlackBerry-Nutzer im Rahmen von Office 365 für mittelständische und große Unternehmen oder Exchange Online ab sofort ohne weitere Kosten von der Synchronisation ihres Smartphones mit Microsoft Exchange Online. Gute Nachrichten auch für Administratoren, die mit der Dienstintegration in das Office 365-Administrationsportal leichtes Spiel haben. Erfahren Sie mehr über die BlackBerry Business Cloud Services für Microsoft Office 365... [... mehr in diesem Blogeintrag auf Giza-Blog.de]
This post is powered by
www.Giza-Blog.de |
©
Copyright 2006-2011 Kay Giza. All rights reserved.
Legal
Dart, Google Javascript Alternative, wurde vor ein paar Monaten vorgestellt und die Webentwickler Szene ist noch etwas gespalten, ob Dart nun überflüssig ist oder einfach nur cool und längst überfällig ist. Um die Sprache näher zu erläutern hat Google die grundlegenden Javascript Basics nach Dart übersetzt. Das Ergebnis ist der “Translator”.

Der Name mag momentan noch nicht ganz passend sein, da es hier nur um eine statische Gegenüberstellung handelt und man kein Javascript Code momentan “konvertieren” kann. Ich vermute es geht irgendwann in diese Richtung
Für die Dart interessierten unter euch: Klick.
„Professional Test Driven Development with C#“ von Jeff McWherter und James Bender erschien im Mai 2011 bei Wiley. Das Buch richtet sich an all die Entwickler, die ihre C#-Anwendungen nach Test-First entwickeln wollen.
Wer sich bisher noch nicht mit dem Thema Test Driven Development (TDD) beschäftigt hat findet in den ersten beiden Teilen des Buches eine gute und ausführliche Einführung ins Thema.
TDD Szenarien aus der Praxis
Der dritte Teil widmet sich den praxisorientierten TDD Szenarien. Im Gegensatz zu vielen anderen Büchern geht es hier um die schwerer zu testenden Teile:
- ASP.Net WebForms
- ASP.Net MVC
- JavaScript
- WPF
- Silverlight
- WCF
Im Buch wird zu jeder dieser Technologien aufgezeigt wo die besonderen Herausforderungen liegen und wie man diese Testen kann. Wann immer möglich sollte man die dazu passenden Patterns verwenden. Geht dies nicht ist man auf sich alleine gestellt: Das Buch erklärt leider nur genau einen Weg um die entsprechende Technologie zu testen.
Werkzeuge und Katas
Als Abschluss gibt es einen Teil der sich den Werkzeugen widmet. Bei der Vielzahl möglicher Test-, Mock- und DI-Frameworks ist es nicht leicht eine Auswahl zu treffen. Die Autoren vergleichen jeweils einige Werkzeuge aus dem gleichen Bereich und nennen die für sie wichtigsten Unterschiede. Auch wenn dies die eigene Recherche nicht ersetzt, so ist dies doch ein guter Ausgangspunkt um seinen Werkzeugkasten zusammen zu stellen.
Im Appendix wir noch auf das Thema (TDD-) Katas eingegangen. Kleinen Übungen sollen einem dabei helfen das gelernte zu verinnerlichen. Die Idee stammt aus dem Kampfsport und hilft dort die richtigen Aktionen und Bewegungen zur richtigen Zeit zu machen. Übertragen auf TDD bedeutet dies: Hat man immer und immer wieder geübt wie man erst einen Test und dann den produktiven Code schreibt, geht dies in einem über und man wendet die gleiche Technik auch mit dem Code direkt vor einem an.
Ein E-Book aber kein PDF
Wiley bietet für dieses Buch eine E-Book Version an, aber leider nur in den Formaten ePub und mobi. Gerade wenn ein Buch viele Code-Beispiele hat habe ich neben der Kindle-Version sehr gerne noch ein PDF. Nicht nur sieht der Code dort meist besser aus, er lässt sich auch einfach kopieren. Mir schein als ob Wiley der Konkurrenz in diesem Bereich noch weit hinterher hinkt.
Fazit
Den beiden Autoren ist in einem oft behandelten Themenbereich ein gutes Werk gelungen. Die beiden Einführungsteile liefern alles nötige Grundwissen damit man auch als Anfänger durchstarten kann. Die Auswahl eines Werkzeugkastens und das vermitteln der Ideen rund um TDD runden dieses Buch ab. Mir fehlen hier einzig noch einige alternative Ansätze zum Testen der behandelten .Net-Komponenten.
„The Art of Unit Testing“ ist zwar immer noch mein Favorit zum Thema TDD, dieses Buch folgt aber mit einem sehr kleinen Abstand.
Zum Buch
„Professional Test Driven Development with C#“ von Jeff McWherter und James Bender, 2011 Wiley, ISBN: 978-0-470-64320-4, 360 Seiten, Englisch
Einsortiert unter:.Net, Bücher Tagged: .Net, Bücher, C#, Clean Code, TDD, Unit Test
Was bisher geschah: TDD im Flow – Teil 1 TDD im Flow – Teil 2 Test #4: Blockierte Entnahme Nun geht es an den Kern meines Abstrakten Datentyps: die Sequentialisierung. Ich muss die Entnahme aus den Queues nach Round Robbin einschränken. Es darf nur entnommen werden, wenn eine Queue nicht gerade blockiert wird. Die Blockierung beginnt, wenn ein Worker aus einer unblockierten Queue entnimmt –
Wer es noch nicht mitbekommen hat, am 4. Mai 2012 findet die 2012er Ausgabe der dotnet Cologne 2012 statt. Wir suchen natürlich noch Sprecher, mit interessanten Themen die wir unseren Teilnehmern anbieten können.
Mir persönlich fehlen noch ein paar Vorträge Absatz des Microsoft Stacks, es gibt Interessante Open Source Tools und Frameworks rund um .NET die noch nicht mit einem Vortrag bedacht sind. Mir liegt viel daran auch dort entsprechendes zu Präsentieren. Von der Einführung bis zum Deep Dive darf alles angeboten werden. Macht die Konferenz Interessant, was für Ihre selbst gerne mal auf einer Konferenz sehen.
Also holt euch euren Zugang zum SpeakerNet der dotnet Cologne und tragt eure Vorschläge ein.
Hier geht es zu unserem Call for Papers https://dotnet-cologne.de/CallForPapers.ashx

Vor einigen Wochen habe ich per Doodle eine kleine Stimmungsumfrage gestartet, um zu sehe, wie das Interesse an einer weiteren Veranstaltung des .NET-Stammtisch Konstanz-Kreuzlingen aussieht.
Kurz nach dem ersten Ansturm auf die Umfrage ist das neue Team dann zusammengesessen und hat überlegt, ob und wie die neue Veranstaltung denn konkret aussehen soll. Uns war wohl allen klar, dass wir die Veranstaltung auf jeden Fall noch einmal versuchen wollen, sofern die Umfrage positiv verläuft. Und so wie es hier aussieht nenne ich das sehr positiv:
Ich möchte mich bei allen Teilnehmern der Umfrage hiermit ganz herzlich bedanken. Dieses Ergebnis hat unsere Motivation für eine weitere Veranstaltung noch mehr verstärkt.
Das Team
Im Team gab es ein paar Veränderungen. So wird uns Golo Roden – der letztes Jahr eine großartige Agenda mit vielen tollen Sprechern aufgestellt hat - leider nicht mehr aktiv im Team unterstützen. Auch Markus Schmid möchte sich dieses Jahr nicht mehr an der Organisation der Veranstaltung beteiligen.
Wenn auch nur im Beck-End, so bekommen wir doch starke Unterstützung von Patrick Kress, der die organisatorischen Fäden (Zügel?) zusammenhalten wird.
Weiterhin mit dabei sind Stefan Zybarth (Combit GmbH) für PR und Helfer, Tilo Schinke (Ontrex AG) für Finanzen, Catering und Location und zu guter Letzt meine Wenigkeit als Ansprechpartner für Sponsoren, Sprecher und Teilnehmer.
Für die Auswahl der Themen möchten wir dieses mal die .NET-Community beauftragen ;-)
Parallel zum CfP starten wir eine Umfrage zur Themenwahl. Sprecher und Vorträge werden wir dann anhand der gewählten Themen aus den Eingängen des CfP auswählen.
Neuer Name
Die Änderung des Namens hatte mehrere Gründe: Zum einen gab es nie eine Party (außer die traditionelle Kennenlern-Party am Vortag) und zum anderen gab es auf der Seiten der Teilnehmer Schwierigkeiten vom Arbeitgeber eine Party am Samstag gezahlt zu bekommen.
Zum anderen wollen wir uns auf das Konferenz-Schema festlegen, da es in dieser Region keine Konferenz dieser Art gibt. Auch wenn es in der .NET-Community den Anschein hat, dass es inzwischen reichlich Veranstaltungen der .NET-Community gibt, so sind es doch viele verschiedene Arten und keine welche den Bodenseeraum und alle vier anliegenden Länder ansprechen soll.
Die Website wird in Kürze unter der Adresse seesharp-conference.net erreichbar sein. Unser Sponsor und Hosting Provider die K&K Internet GmbH wird die nötigen Einstellungen im IIS noch machen müssen und wir werden noch ein paar Änderungen auf der Website machen müssen.
Als Twitter-Hashtag wird wohl #SSC12 herhalten.
Location und Termin
Die See# Conference wird, wie die Veranstaltungen zuvor wieder im DREISPITZ Sport- und Kulturzentrum in Kreuzlingen statt finden. Hier sind wir gut betreut, fühlen uns wohl, der Caterer hat eine Küche vor Ort. Weiterhin bekommen wir als Kreuzlinger Verein die Location zum halben Preis und die Stadt Kreuzlingen freut sich, dass sie auch eine IT-Veranstaltung im Angebot hat :-)
Was den Termin angeht, so können wir unser Versprechen, einen Termin außerhalb der Sommerferien zu finden, leider nur für die Schweiz einlösen. Der Termin für die See# Conference 2012 wird
Freitag der 31. August 2012
sein. Das war der einzige Termin der im Spätsommer, bzw. Herbst noch frei war. Das nächste mal werden wir wohl schon 14 Monate im Voraus buchen müssen. Allerdings spricht das ja auch für das DREISPITZ. Vielen Dank - an dieser Stelle - an die Stadt Kreuzlingen für die Unterstützung bei der Terminfindung. (Ich freu mich schon jetzt wieder auf die interessanten Gespräche mit dem Hauswart Herrn Keller *fg*)
Verpflegung
Erst der Negative Punkt: Bei der letzten Veranstaltung mussten wir sehr viele Flaschen selber einsammeln und in die bereitgestellten Behälter entsorgen, aber das alleine ist nicht das Problem, sondern die Tatsache, dass die ca. Hälfte dieser Flaschen nicht ganz lehr waren, bzw. teilweise noch mehr als halb voll waren. Da der Inhalt der Flaschen einen gewissen Wert besitzt der auf die Teilnehmer umgeschlagen werden muss und da es einfach nur schade darum ist Lebensmittel entsorgen zu müssen, wollen wir das aus Ökologischen und Ökonomischen gründen von vornherein begrenzen. Wir werden deshalb, wie bei der ersten Veranstaltung, nur drei Getränke kostenfrei bereitstellen. Alle weiteren Getränke werden zum Selbstkostenpreis abgegeben. Außerdem werden wir ein Flaschenpfand einführen.
Die positiven Punkte: Der negative Punkt gilt nur für Softdrinks in Flaschen. Kaffee und Tee gibt es natürlich weiterhin kostenfrei. :-) Als Caterer werden wir schauen dass wir wieder das Hotel ZIIL bekomme können. Im Gegensatz zum Caterer der ersten See# Party, lief die Abwicklung mit dem Hotel ZIIL absolut stressfrei und lecker war es auch.
Also…
…alle die in der Umfrage für die Veranstaltung gestimmt haben möchte ich auch auf der See# Conference sehen ;-)
Ich freue mich drauf ein drittes mal eine solche Veranstaltung machen zu können und lade alle herzlich dazu ein, als Teilnehmer, als Sponsor oder als Sprecher, das Event einen noch größeren Erfolg werden zu lassen als die vergangenen Veranstaltungen :-)

Manche Organisationen haben für das Product Backlog Management ein zentrales Master Backlog, von welchem die Product Backlog Items (PBI) dann verschieden Sub-Teams zugewiesen werden. Diese Teams arbeiten in Ihrem eigenen separaten Product Backlog. Mit TFS 11 können wir nun dieses Konzept direkt konfigurieren, dabei wird der AreaPath verwendet um die Hierarchie abzubilden.

Master Backlog:

Die Zuweisung zu einem Team Backlog erfolgt über den AreaPath des PBI’s:

Dann findet man im Sub Team Backlog das PBI. Über die Konfiguration kann festgelegt werden, ob dass PBI noch im Master Backlog nach einem Refresh sichtbar sein soll oder nicht.

Wie konfiguriere ich das Ganze? Gregg hat einen Post verfasst, wie man Schritt für Schritt das Master Sub-Team Konzept konfiguriert.
Hinweis: In dem TFS 11 CTP Build ist diese Funktionalität nicht enthalten, erst mit der TFS 11 Beta oder jetzt schon mit dem TFS Service.
Letztes Jahr habe ich hier im Blog Anleitungen bzw. How-To-Guides rund um die Dienstkonfiguration von Office 365 für verschiedenste Hoster veröffentlicht. Wie füge ich bei Office 365 meine Domain (bzw. Domäne) hinzu und lasse sie überprüfen? Wie richte ich bei Office 365 die Dienste Exchange Online, Lync und SharePoint ein?
Herausgekommen sind 20 sehr umfangreiche Anleitungen. Damit diese stetig aktuell sind, auch von jedermann bearbeitbar sind (denn Sie als Office 365 Anwender bzw. Administrator machen sicherlich ihre ganz eigenen Erfahrungen und sammeln auch Tipps und Tricks), haben wir die Anleitungen in das offizielle Microsoft Office 365 Wiki gestellt.
Bitte beachten Sie daher... [... mehr in diesem Blogeintrag auf Giza-Blog.de]

This post is powered by
www.Giza-Blog.de |
©
Copyright 2006-2011 Kay Giza. All rights reserved.
Legal
In der ersten Folge dieser Architektur-Serie, haben wir die Phasen Vision, Diagnose und Analyse kennengelernt. Dabei wurde auf das Thema Kommunikation eingegangen und das diese durch Metaphorik (Zum Beispiel durch die Common Language) vereinheitlicht wird. Es begann mit Sketching, Modellierung und endete mit Prototyping.
In diesem Teil wird die Design- und Development-Phase vorgestellt, womit das Ziel mit dem Spiel „GoFish“ immer näher rückt.
Das Design

Wir beginnen mit der Design-Phase. Auch Entwurfsphase genannt.
- Ziel der Design Phase ist die Festlegung, wie die Geschäftsanforderungen zu implementieren sind. Diese Phase konzentriert sich in erster Linie auf den Entwurf und die Einschätzung des erforderlichen Aufwands für die Entwicklung individueller Anpassungen.
- Die wichtigsten Zielvorgaben sind produktspezifische, detaillierte Designspezifikationen, sowie Test Case Dokumente, welche die Funktionstests spezifizieren.
Die Abstraktion der Anforderungen
Die bisherigen Phasen konnten beim Auffinden der Anforderungen bestens weiterhelfen. In der Regel werden bereits beim Aufbau der “Common Language” sogenannte “User Stories” vom Kunden beschrieben. Das Schreiben von User-Stories verlangt allerdings eine Art Disziplin. Sie sollten in der Sprache des Kunden liegen. Daher sollen technische Aspekte auf keinen Fall enthalten sein. Genau aus diesem Grund, sollte auch der Kunde „eigentlich“ selbst die User-Stories schreiben.

Abbildung 1 – Die Abstraktionspyramide
Ein Beispiel als User-Story: „Beim Spielstart werden 52 Karten gemischt.“
Nun hat der Kunde seinen Prototyp erhalten und kann mittels SketchFlow-Player direkt Feedback an den Designer abgeben. Gleichzeitig wird der Entwickler mit der Abstraktion der Anwendungsfälle (User-Stories) zu einzelnen Tasks beginnen. Diese Tasks beschreiben die benötigten Schritte um die Anforderung zu erfüllen.
Als Beispiel sind hier die Tasks zur oben angezeigten User-Story gelistet:
1: Modellieren
2: Code generieren / anlegen
3: Anforderung via Test festlegen
4: Logik implementieren
5: Logik mit anderer Logik koppeln
Schnell wird ersichtlich, dass aus einer einfachen Anforderung viele Tasks entstehen. Anschließend können die User-Stories noch vom Kunden priorisiert und die Tasks vom Entwickler-Team geschätzt werden. Wichtig! Aus Zeitgründen muss oft schon auf User-Story-Ebene eine Zeitschätzung stattfinden, welche dadurch ungenau ausfällt . Zum Schätzen der Zeit kann ich Planning-Poker bestens empfehlen.
Für “GoFish” hatte ich keine User-Stories und Tasks eingeplant. In der Regel erstelle ich für meine privaten Projekte immer eine Art User-Stories und Tasks. Es kann auch nur zur stätigen Übung für sich selbst dienen. Allerdings soll diese Architekturserie nicht den Rahmen sprengen. Zur weiteren Arbeit reichen die Aktivitätsdiagramme und das Komponentendiagramm bestens aus.
Komponentendiagramm
Die Design-Phase hat nichts mit dem „Aussehen“, sondern mit dem „entwerfen“ der Software zu tun. In dieser Phase sollten alle Anforderungen weit möglichst bekannt sein. Jetzt gilt es diese Anforderungen in Komponenten aufzuteilen. Somit erhalten wir für unsere Architektur eine Flexibilität und bleiben jederzeit offen für Erweiterungen.
Eine Komponente ist eine modulare Einheit, die innerhalb ihrer Umgebung austauschbar ist. Die internen Daten sind ausgeblendet, aber Komponenten verfügen über eine oder mehrere klar definierte Schnittstellen, über die auf die Funktionen zugegriffen werden kann.
Zum Designen der Komponenten, verwende ich das Komponentendiagramm (engl. component diagram - UML). Auch dieses UML-Diagramm ist in den Architecture Tools von Visual Studio 2010 Ultimate enthalten.
Das Zeichnen von Komponentendiagrammen hat mehrere Vorteile:
- Bei einem Komponentendiagramm werden die Abhängigkeiten der Komponenten untereinander ersichtlicher.
- Wenn sich das Entwicklungsteam auf die Hauptblöcke eines Entwurfs konzentriert, kann es ein besseres Verständnis des vorhandenen Entwurfs entwickeln und einen entsprechenden neuen Entwurf erstellen.
- Indem Sie sich Ihr System als Auflistung von Komponenten mit klar definierten, angebotenen und erforderlichen Schnittstellen vorstellen, optimieren Sie die Abgrenzung zwischen den Komponenten. Dadurch ist der Entwurf einfacher zu verstehen, und er kann bei sich ändernden Anforderungen auch einfacher angepasst werden.
- Der Entwurf dient später auch für ein „Design by contract“. Womit Schnittstellen (Interfaces) für die Komponenten angelegt werden. Diese dienen dann als Vertrag (contract) für das gesamte Entwicklerteam.
Als Vorlage zum Modellieren der Komponenten, dienen die bereits erzeugten Workflows (Aktivitätsdiagramme). Hieraus erstellte ich pro Aktivität eine eigene Komponente. Die Schnittstelle der Komponenten war aus dem Domänenmodell bezogen und wurde somit immer auf eine Liste von Spielkarten (List<Card>) definiert. Dabei betrachtete ich das Expert-Muster, welches besagt: „Eine Aufgabe sollte von der Entität ausgeführt werden, die im Bezug darauf Experte ist.“.
Allerdings sollen Entities keinerlei Logik beinhalten und als einfache POCO‘s (Plain old CLR Object’s) behandelt werden. Als Lösung für die meisten Anforderungen von “GoFish”, eignen sich Extension-Methods geradezu ideal.
Normal steht eine Schnittstelle für eine Methode, so wie es beim CardsGenerator mit der Methode GetCards demonstriert wird (siehe Abbildung 2). Da ich allerdings später die Logik mittels Workflow Foundation 4 koppeln möchte, wird zu jeder Funktion eine weitere Facade-Komponente entwickelt. Womit ich bei der Extension-Methods-Lösung zufrieden bin.

Abbildung 2 – Aus den Aktivitäten der Workflows werden Komponenten angelegt.
Die einzelnen „Extension-Methods“-Komponenten verschachtel ich in eine CardsExtensionMethods-Komponente und definiere nur noch die Schnittstellen. Somit befinden sich die Funktionalitäten wieder in einem eigenen Kontext.

Abbildung 3 – Viele einzelne Komponenten werden zu einer kombiniert.
Die Schichtenarchitektur
Wobei jetzt grob die einzelnen Funktionalitäten definiert wurden, soll nun ein Schema der Architekturart folgen. Das wird in der Regel auch als Erstes modelliert. Bei diesem Spiel handelt es sich um einen Fat Client. Dabei soll die Schichtenarchitektur als fundamentale Grundlage dienen. Die Schichtenarchitektur bezeichnet grundsätzlich ein Architekturmuster, worin einzelne Aspekte des Softwaresystems konzeptionell einer Schicht (engl. layer) zugeordnet werden. Die erlaubten Abhängigkeitsbeziehungen zwischen den Aspekten werden bei einer Schichtenarchitektur dahingehend eingeschränkt, dass Aspekte einer „höheren“ Schicht nur solche „tieferer“ Schichten verwenden dürfen. Ein System mit einer Schichtenarchitektur bezeichnet man auch als mehrschichtig.
Die den Schichten zugeordneten Aspekte können dabei je nach Art des Systems oder Detaillierungsgrad der Betrachtung z. B. Funktionalitäten, Komponenten oder Klassen sein. Ich verwende für jede Schicht ein eigenes Assembly-Projekt. Das ermöglicht einen hohen Grad von Abstraktion und Austauschbarkeit. Womit eine hohe Flexibilität der Architektur gegeben wird.
Mein Tipp! HowTo: 3-Tier / 3-Schichten Architektur und Ist eine 3 Schichten Architektur mit eigener DAL immer empfehlenswert?
Das 2- oder 3-Schichten-Modell?
Die erste Schicht besteht immer aus der auszuführenden Assembly (*.exe). In diesem Fall handelt es sich demnach um ein WPF-Projekt. Die zweite Domain-Schicht beinhaltet die Spielablauflogik. Im Geschäftsumfeld auch als Businesslogic bekannt, welche hier den Ablauf der Geschäftslogik regeln würde (zum Beispiel Zustandsvalidierungen, Berechnungen etc.). Die letzte Schicht ist in der Regel die Datenschicht (DataAccessLayer). Allerdings steht nirgends bei den Anforderungen beschrieben, dass Informationen persistent gespeichert werden sollen, womit auch eine Planung mit einem 2-Schichten Modell vollkommen ausreicht. Die zwei Schichten benötigen allerdings die Daten vom DomainModel (Entities), Contracts (Interfaces), Handler, Services, Aspekte und vieles weitere. Wenn diese Daten in der ersten Schicht untergebracht werden, müsste die zweite Schicht darauf referenzieren, was laut der Schichtenarchitektur strikt untersagt ist. Zudem muss die erste Schicht auch die Funktionen der zweiten aufrufen können. Explizit dafür wird eine weitere Querschicht GoFish.Common hinzugefügt. Jede Schicht ist somit verpflichtet die Common-Layer zu referenzieren.
Für jede Schicht wird eine Komponente angelegt und bekommt den Titel der späteren Assembly.

Abbildung 4 – Passend zum Komponentendiagramm werden neue Projekte angelegt. Diese fungieren jeweils als Layer (Schicht).
Das Ebenendiagramm (Layer-Diagram)
Für eine bessere visuelle Darstellung der Schichten, gibt es das Layer-Diagram. Auch dieses UML-Diagramm ist in den Architecture Tools von Visual Studio 2010 Ultimate enthalten. Sie können mit dem Layer-Diagram die vorgesehenen oder vorhandenen Abhängigkeiten zwischen bestimmten Schichten darstellen. Diese Abhängigkeiten geben an, welche Schichten die Funktionen auf anderen Schichten verwenden können oder gegenwärtig verwenden. Durch das Gliedern des Systems in Schichten, die verschiedene Rollen und Funktionen beschreiben, kann ein Ebenendiagramm das Verstehen, Wiederverwenden und Verwalten des Codes für Sie erleichtern.
Sie können mit einem Ebenendiagramm die folgenden Aufgaben ausführen:
- Angeben der vorhandenen oder vorgesehenen logischen Architektur des Systems
- Ermitteln von Konflikten zwischen dem vorhandenen Code und der vorgesehenen Architektur
- Visualisieren der Auswirkungen von Änderungen an der vorgesehenen Struktur, wenn Sie das System umgestalten, aktualisieren oder weiterentwickeln
- Erzwingen der vorgesehenen Architektur während der Entwicklung und Wartung des Codes, indem Sie in die Eincheck- und Buildvorgänge Validierung einschließen

Abbildung 5 – Die Schichten visuell darstellen mit dem Layer-Diagram. Die erlaubte Abhängigkeit wird durch Pfeile dargestellt.
Mein Tipp! Visual Studio 2010: Architektur-Validierung - Arbeiten mit Layerdiagrammen
Modellgetriebene Architektur (Model Driven Architecture, MDA)
Ein Teil der modellgetriebenen Architektur ist die modellgetriebene Softwareentwicklung (MDSD). MDSD (Model Driven Software Development) bezeichnet die Verwendung von Modellen und Generatoren zur Verbesserung der Softwareentwicklung. Schon in den Anfangszeiten der Informatik stützte man sich auf Modelle und entwickelte Generatoren, um schematischen Quellcode daraus zu erzeugen.
DomainModel zu Entities generieren
Beim Projekt “GoFish” kann ebenfalls ein minimaler Teil von MDSD mit den bereits erzeugten UML-Diagrammen genutzt werden. So lässt sich das DomainModel nun in Entity-Klassen generieren.
Wichtig! Hierfür muss vorher das Visual Studio 2010 Feature Pack installiert werden. Ansonsten ist die Funktionalität nicht vorhanden.
Um jetzt den Code generieren zu lassen, wird das DomainModel-Diagram geöffnet. Im Drop-Down-Menü vom Designer (Rechtsklick auf eine freie Fläche), wird der Menüpunkt “Generate Code” angeboten (siehe Abbildung 6).

Abbildung 6 – Aus dem Visual Studio 2010 UML-Designer den Code generieren lassen.
Etwas unschön ist, dass die Klassen willkürlich im eigenen Projekt erzeugt wurden. Jedoch erwartet man nach der Schichtenarchitektur, das die Entities in die GoFish.Common-Schicht unter dem Verzeichnis Entities generiert werden. Diesen Wunsch kann man unter Visual Studio 2010 selbst konfigurieren. Eine Konfiguration wird auch Projektspezifisch durchgeführt. Daher müssen bei einem neuen Projekt die Einstellungen wiederholt angepasst werden. Die Konfiguration befindet sich in Visual Studio 2010 im Menüpunkt “Architecure – Configure Default Code Generation Settings…” – (siehe Abbildung 7).

Abbildung 7 – Die Code Generation Settings öffnen.
In der “Code Generation”-Konfiguration müssen vom ClassTemplate die Properties “Project Path” und “Target Directory”, wie unter Abbildung 8 geändert werden.

Abbildung 8 – Die Code Generation Settings.
Anschließend wird der Code “fast” wie erwünscht im Projekt erzeugt. Die einzige Kritik meinerseits ist, dass die Namespace-Definition der generierten Klassen fehlt. Man muss daher selbst im T4-Template diesen Wunsch einbauen (siehe Abbildung 8 – Template File Path). Ich hatte “etwas unschön” mit ReSharper manuell die Entities mit dem fehlenden Namespace erweitern lassen. Bei einer wiederholten Code Generierung müsste ich diesen Schritt erneut ausführen.

Abbildung 9 – Die vom DomainModel generierten Entity-Klassen.
Leider können allerdings vom Komponentenmodell keine Interfaces (Contracts) generiert werden. Diese erzeugte ich anhand des Diagramms manuell. Ich habe die Contracts erzeugt, die laut Komponentendiagramm instanziiert werden müssen. Das Projekt hat nun durch die Design-Phase seine Infrastruktur erhalten. Auch Interfaces (Contracts) und Entities wurden angelegt.

Abbildung 10 – Die erste Projektinfrastruktur, Entities und Contracts von GoFish sind nun fertiggestellt.
Development

Wir beginnen mit der Development-Phase, auch Entwicklungsphase genannt.
- Ziel der Development Phase ist es, die in den Designspezifikationen festgelegten und genehmigten Anpassungen, Berichte, Integrationen und Datenmigrationsprozesse zu entwickeln und zu testen.
- Die wichtigsten Zielvorgaben sind die getesteten und überprüften Komponenten und Prozesse.
Testgetriebene Entwicklung (engl. Test-Driven Development (TDD))
Für die Planung sind nun alle wichtigen Aspekte erfüllt worden. Ich habe mir nun eine Vorlage von Klassen und Interfaces angelegt, und muss nur noch die Logik dazu implementieren. Als Entwicklungsstil verwende ich schon seit Jahren die testgetriebene Entwicklung (Test-Driven Development, kurz TDD). Bei TDD wird vor der Implementierung der Logik, ein Unit-Test geschrieben. Diese sollen unter TDD die funktionale Anforderung einer Komponente sicherstellen. Im Gegenteil zu klassischen Unit-Tests, die Komponenten nur auf Seiten Effekte testen. Somit wird das “Test” von Test-Driven Development gerne verwechselt und Anhänger dieser Praxis haben daher eine Ergänzung mit Behavior-Driven Development (BDD) ins Leben gerufen. Für klassische Unit-Tests gibt es bereits zahlreiche Tools, die automatisch einen passenden Test Code zur Komponente generieren (siehe zum Beispiel Microsoft Pex).
Mein Tipp! Unit-Test Generierung mit PEX - Whitebox Testing
Als Unit-Test Framework habe ich mich für das Open-Source Framework NUnit entschieden.
Hier nochmal der TDD Prozess im Detail:
- Schreibe den Testcode
- Mache ihn kompilierbar
- Starte den Test und lasse ihn fehlschlagen
- Setze nur die Anforderung um, damit der Test abgedeckt ist
- Starte den Test und prüfe, ob er erfolgreich ist
- Refactore den Code zur besseren Übersichtlichkeit und Vermeidung von Coderedundanzen
- Starte von Vorne mit dem nächsten Test
Also begann ich erst mit dem Schreiben der Tests. Welche Funktionen getestet/implementiert werden müssen, beschreibt uns das Komponentendiagramm (siehe Abbildung 11).

Abbildung 11 – Die beschriebenen Schnittstellen vom Komponentendiagramm werden mittels “Test-First” implementiert.
Beim Schreiben von Unit-Tests gibt es eigene Prinzipien zu beachten, die sich mit gängigen OOP-Prinzipien unterscheiden. Eines davon wäre die AAA-Syntax. (Weitere Infos darüber unter: TDD – Probleme vermeiden mit der AAA-Syntax). Den Source-Code für die Unit-Tests stehen unter Listing 1 & 2.
Mein Tipp! TDD Anti-Patterns - Am schlechten Beispiel lernen
1: using System.Collections.Generic;
2: using GoFish.Common.Entities;
3: using GoFish.Common.Extensions;
4: using GoFish.Domain;
5: using NUnit.Framework;
6:
7: namespace GoFishGame.Tests
8: {
9: [TestFixture]
10: public class GameSetUpTests
11: {
12: [Test]
13: public void GetCards_ShouldBeGetFiftyTwoCardsWithNonDublicate()
14: {
15: // Arrange
16: CardsGenerator cardsGenerator = new CardsGenerator();
17:
18: // Act
19: List<Card> results = cardsGenerator.GetCards();
20:
21: // Assert
22: Assert.AreEqual(52, results.Count);
23:
24: CardDublicateCheck(results);
25: }
26:
27: [Test]
28: public void GetFiveRandomCards_ShouldBeFiveNonDublicateCards()
29: {
30: // Arrange
31: CardsGenerator cardsGenerator = new CardsGenerator();
32: List<Card> results = cardsGenerator.GetCards();
33:
34: // Act
35: List<Card> randomKarten = results.GetFiveRandomCards();
36:
37: // Assert
38: Assert.AreEqual(randomKarten.Count, 5);
39: Assert.AreEqual(results.Count, 47);
40:
41: CardDublicateCheck(randomKarten);
42: }
43:
44: private static void CardDublicateCheck(List<Card> results)
45: {
46: foreach (Card card in results)
47: {
48: var containsCount = results.FindAll(x => x == card);
49:
50: if (containsCount.Count > 1)
51: Assert.Fail("Card is dublicate");
52: }
53: }
54: }
55: }
Listing 1 – Der GameSetUp Test-Code.
1: using System.Collections.Generic;
2: using GoFish.Common.Entities;
3: using GoFish.Common.Extensions;
4: using GoFish.Domain;
5: using NUnit.Framework;
6:
7: namespace GoFishGame.Tests
8: {
9: [TestFixture]
10: public class GameCoreLogicTests
11: {
12: [Test]
13: public void FindQuartets_GiveTenCardsWithTwoQuartets_ShouldBeGetTwoQuartets()
14: {
15: // Arrange
16: List<Card> cards = new List<Card>();
17:
18: Card karte = new Card { Value = ValueType.Ass };
19: Card karte2 = new Card { Value = ValueType.Ass };
20: Card karte3 = new Card { Value = ValueType.Zwei };
21: Card karte4 = new Card { Value = ValueType.Ass };
22: Card karte5 = new Card { Value = ValueType.Fünf };
23: Card karte6 = new Card { Value = ValueType.Ass };
24: Card karte7 = new Card { Value = ValueType.Zwei };
25: Card karte8 = new Card { Value = ValueType.Zwei };
26: Card karte9 = new Card { Value = ValueType.Zwei };
27:
28: cards.Add(karte);
29: cards.Add(karte2);
30: cards.Add(karte3);
31: cards.Add(karte4);
32: cards.Add(karte5);
33: cards.Add(karte6);
34: cards.Add(karte7);
35: cards.Add(karte8);
36: cards.Add(karte9);
37:
38: Player player = new Player { Cards = cards };
39:
40: // Act
41: List<Card> quartets = player.Cards.FindQuartets();
42:
43: // Assert
44: Assert.AreEqual(8, quartets.Count);
45:
46: List<Card> assQuartet = quartets.FindAll(karteItem => karteItem.Value == ValueType.Ass);
47: List<Card> zweiQuartet = quartets.FindAll(karteItem => karteItem.Value == ValueType.Zwei);
48:
49: Assert.AreEqual(4, assQuartet.Count);
50: Assert.AreEqual(4, zweiQuartet.Count);
51: }
52:
53: [Test]
54: public void FindQuartets_GiveFiveCardsWithNonQuartet_ShouldBeGetZeroQuartets()
55: {
56: // Arrange
57: List<Card> cards = new List<Card>();
58:
59: Card card = new Card { Value = ValueType.Ass };
60: Card card2 = new Card { Value = ValueType.Ass };
61: Card card3 = new Card { Value = ValueType.Zwei };
62: Card card4 = new Card { Value = ValueType.Ass };
63: Card card5 = new Card { Value = ValueType.Fünf };
64:
65: cards.Add(card);
66: cards.Add(card2);
67: cards.Add(card3);
68: cards.Add(card4);
69: cards.Add(card5);
70:
71: Player player = new Player { Cards = cards };
72:
73: // Act
74: List<Card> quartets = player.Cards.FindQuartets();
75:
76: // Assert
77: Assert.AreEqual(0, quartets.Count);
78: }
79:
80: [Test]
81: public void GetSameValueCards_SetSecondAssCard_ShouldBeGetOneAssCard()
82: {
83: // Arrange
84: List<Card> cards = new List<Card>();
85:
86: Card card = new Card {Value = ValueType.Acht};
87: Card card2 = new Card { Value = ValueType.Bube };
88: Card card3 = new Card { Value = ValueType.Zwei };
89: Card card4 = new Card { Value = ValueType.Ass };
90: Card card5 = new Card { Value = ValueType.Fünf };
91:
92: cards.Add(card);
93: cards.Add(card2);
94: cards.Add(card3);
95: cards.Add(card4);
96: cards.Add(card5);
97:
98: Card selectedCard = new Card {Value = ValueType.Ass};
99:
100: // Act
101: List<Card> sameCards = cards.GetSameValueCards(selectedCard.Value);
102:
103: // Assert
104: Assert.AreEqual(sameCards.Count, 1);
105: Assert.AreEqual(cards.Count, 4);
106: Assert.AreEqual(sameCards[0].Value, ValueType.Ass);
107: }
108:
109: [Test]
110: public void GetCard_GiveFiftyOneCards_ShouldBeGetOneRandomCard()
111: {
112: // Arrange
113: CardsGenerator cardsGenerator = new CardsGenerator();
114: List<Card> cards = cardsGenerator.GetCards();
115:
116: // Act
117: Card card = cards.GetCard();
118:
119: // Assert
120: Assert.AreEqual(cards.Count, 51);
121: Assert.NotNull(card);
122: Assert.AreEqual(typeof(Card), card.GetType());
123: }
124:
125: [Test]
126: public void GetTheWinner_WithMostQuartets()
127: {
128: // Arrange
129: List<Card> playerCardsA = new List<Card>();
130:
131: Card card = new Card { Value = ValueType.Ass };
132: Card card2 = new Card { Value = ValueType.Ass };
133: Card card3 = new Card { Value = ValueType.Ass };
134: Card card4 = new Card { Value = ValueType.Ass };
135:
136: playerCardsA.Add(card);
137: playerCardsA.Add(card2);
138: playerCardsA.Add(card3);
139: playerCardsA.Add(card4);
140:
141: Player playerA = new Player {Name="Bob", Quartets = playerCardsA};
142:
143: List<Card> playerCardsB = new List<Card>();
144:
145: Card cardB = new Card { Value = ValueType.Acht };
146: Card cardB2 = new Card { Value = ValueType.Acht };
147: Card cardB3 = new Card { Value = ValueType.Acht };
148: Card cardB4 = new Card { Value = ValueType.Acht };
149: Card cardB5 = new Card { Value = ValueType.Dame };
150: Card cardB6 = new Card { Value = ValueType.Dame };
151: Card cardB7 = new Card { Value = ValueType.Dame };
152: Card cardB8 = new Card { Value = ValueType.Dame };
153:
154: playerCardsB.Add(cardB);
155: playerCardsB.Add(cardB2);
156: playerCardsB.Add(cardB3);
157: playerCardsB.Add(cardB4);
158: playerCardsB.Add(cardB5);
159: playerCardsB.Add(cardB6);
160: playerCardsB.Add(cardB7);
161: playerCardsB.Add(cardB8);
162:
163: Player playerB = new Player {Name="Lucky Man", Quartets = playerCardsB};
164: Player playerC = new Player {Name = "Looser"};
165:
166: GamblingTable gamblingTable = new GamblingTable();
167: gamblingTable.Players.Add(playerA);
168: gamblingTable.Players.Add(playerB);
169: gamblingTable.Players.Add(playerC);
170:
171: // Act
172: string playername = gamblingTable.Players.GetTheWinner();
173:
174: // Assert
175: Assert.AreEqual("Lucky Man", playername);
176: }
177: }
178: }
Listing 2 – Der GameCore Test-Code.
Die Lösung konnte ich ideal mit Extension-Methods umsetzen. Dass die Logik auch nach den Vorgaben funktioniert, zeigt die Grüne-Welle der Unit-Tests (siehe Abbildung 12).

Abbildung 12 – Die Tests wurden alle erfolgreich erfüllt.
Zusammenfassung und Vorschau auf den nächsten Teil
Wir haben nun gemeinsam an den Phasen Design und Development geschnuppert. Auch wenn der Punkt Development nicht komplett abgeschlossen wurde, somit ist zumindest die Hauptlogik durch TDD implementiert worden. Das angenehme an TDD ist, dass ich derzeit noch keine Oberfläche (Frontend) für mein Spiel benötige. Ich kann jederzeit per Knopfdruck überprüfen ob alle gewünschten Anforderungen noch wie erwartet funktionieren. Parallel dazu, kann bei WPF die Oberfläche von einem professionellen Grafik-Designer entworfen werden.
Bei der Design-Phase wurden die jeweiligen Prozesse zu Komponenten abstrahiert. Aus den Komponenten entstanden die jeweiligen Schichten und Contracts (Interfaces). In der Praxis vermischen sich gerne auch Phasen untereinander. So vermischt sich oft die Analyse-Phase mit der Design-Phase.
Beim nächsten Teil werden wir die Development-Phase fortsetzen. Dazu wird jede Komponente durch ein Activity (Workflow Foundation 4) erweitert und die ersten Workflows definiert.
Viel Spaß und bis zur nächsten Folge, wenn Ihr mögt!
Wer aller muss E-Mails oder Newsletter aus eigenen Applikationen versenden? Nun, viele Apps tun genau das: Sie informieren über bestimmte Aktionen per E-Mail. Und wie macht man das am besten?
Hm, früher hat man noch seinen eigenen E-Mail Server, SBS oder was auch immer verwendet. Security und Spam sind da oft ein Thema beim Betreiben eines eigenen E-Mail-Systems. Darum wollen sich Developer meistens nicht kümmern (müssen).
Heute verwendet man dazu Cloud Services wie Office 365. Oder: Windows Azure!
Dazu gibt es eine tolle Aktion:
25.000 E-Mails per SendGrid versenden – für alle Windows Azure Kunden frei!
http://sendgrid.com/azure.html

Danke an Christian Weyer, thinktecture, MVP for Connected Systems, für den Tipp in unserer cloudusergroup!

Nach der erfolgreichen Serie über Knockout.js und dem durchwegs positiven Feedback, möchte ich - wie bereits angekündigt - eine neue Serie starten. Diese beschäftigt sich mit Backbone.js. In dieser Vorabinformation möchte ich kurz darauf eingehen, was der Leser erwarten darf. Und das ist eine ganze Menge, da diese Serie einen gänzlich anderen Weg einschlagen wird.
Praxisbeispiel
Im Rahmen der Knockout.js-Serie wurden unterschiedliche Beispiele behandelt. Diese wurden möglichst nahe an der Realität gehalten, aber es mussten auch Teile konstruiert werden. Dies soll in dieser Serie anders sein.
Im Rahmen der Backbone.js-Serie wird ein bereits bestehendes Projekt neu implementiert. Konkret geht es um meine Website http://wpf-blogger.com. Diese aggregiert Feeds von Bloggern zu WPF, Silverlight und Windows Phone in mehreren Sprachen. Damit soll einschlägigen Entwicklern eine zentrale Anlaufstelle für aktuelle Tipps, Tricks und Techniken auf Basis der genannten Technologien geboten werden.
Diese Entscheidung hat mehrere Hintergründe: So besteht die aktuelle WPF-Blogger bereits unverändert seit mehreren Jahren und bedarf zahlreicher Neuerungen. Da mir eine Weiterentwicklung auf der aktuellen Basis wenig zielführend erscheint, habe ich mich dazu entschieden, auf aktuelle Technologien und Techniken zu setzen, auch wenn manches davon als Hype angesehen werden kann.
Was kann der Leser nun erwarten?
Da ein konkretes Projekt zur Umsetzung gelangt, wird die Backbone.js-Serie einen hohen Grad an Praxiswissen und - im Rahmen der Umsetzung gemachten - Erfahrungen aufweisen. Ideal, um sich ein Bild über diese Bibliothek zu machen und einen etwaigen eigenen Einsatz besser abschätzen zu können.
Ein weiterer Mehrwert besteht sicherlich darin, dass ich - als der Autor dieser Serie - Backbone.js gerade erst lerne. Daher sind zahlreiche Hinweise auf Fallen und Tücken zu erwarten, in die ich getreten bin - oder noch treten werde.
Großes Augenmerk werde ich auch auf die Themen Konzept und Testing legen.
Eingesetzte Technologien und Bibliotheken
Das Projekt soll aus aktueller Sicht folgende (Quasi-)Standards, Technologien und Bibliotheken umfassen:
- HTML5
- CSS3
- jQuery
- Backbone.js
- .NET
Sollte sich die Notwendigkeit ergeben, weitere Bibliotheken zu verwenden, wird diese Liste entsprechend erweitert.
Hinweis: Die obige Liste setzt auf weit mehr als nur Backbone.js. Auch diese werden in dieser Serie teilweise besprochen/diskutiert. Das Hauptaugenmerk wird jedoch auf Backbone.js gelenkt.
Sourcecode / Sharing
Jeder soll sich den aktuellen Sourcecode ansehen, aber auch für eigene Projekte verwenden können. In der Knockout.js-Serie habe ich hierfür teilweise JSFiddle verwendet, ist aber in diesem Rahmen nicht sehr zielführend. Aus diesem Grund habe ich mich entschieden, das gesamte Projekt auf github zu hosten.
Inhalt
Die einzelnen Teile dieser Serie sind nicht im Vorab festgelegt, sondern ergeben sich aus der laufenden Entwicklung des Projektes. Die untenstehende Liste ist daher als flexibel anzusehen und wird ständig erweitert bzw. auf dem aktuellen Stand gehalten.
Auf neue Teile wird zusätzlich über Twitter hingewiesen.
Feedback
JavaScript, HTML5 und CSS3 waren bis dato nicht mein Hauptscope. Daher ist es sehr wahrscheinlich, dass jede Menge meines Codes einfacher, schöner und besser geschrieben werden kann. Damit die Leser, die, so wie ich, ebenfalls keine Gurus auf diesem Gebiet sind, sich weiterentwickeln, hoffe ich auf zahlreiches Feedback. Darum bitte ich schon jetzt die Gurus unter meinen Lesern, mit ihrer Meinung nicht hinter den Berg zu halten.
Eigentlich habe ich das Thema inzwischen satt, ich beobachte es schon seit knapp einem Jahr und nirgends sind klare Aussage zu finden, sondern nur wilde Spekulationen. Das ging im letzten halben Jahr nicht nur so weit, dass Silverlight in Frage gestellt worden ist, sondern auch das .NET Framework.
Klar ist, dass von Microsoft keine klaren Informationen zu dem Thema kommen. Klar ist dass es dadurch etwas Verunsicherung beim Thema Silverlight gibt.
Ich teile die Meinung, dass Silverlight-Projekte im Moment eine schlechte Idee seien, absolut nicht. Vielleicht bin ich aber auch nicht paranoid genug… ;-)
Wie auch immer… komme ich im Moment entwickelnd und beratend mit einigen neuen Silverlight-Projekten in Berührung. Es stehen auch einige Anfragen an… Aus meiner Sicht gibt es im Moment keinen Grund zu behaupten, dass Silverlight tot ist. Andererseits gibt es auch keine Informationen ob es ein Silverlight 6 geben wird oder nicht. Im Gegenteil konzentriert sich Microsoft auf HTML5
Aber ist das schlimm? Könnte das ein Problem für Silverlight sein?
Aus meiner Sicht nicht. Denn in einem einzigen Punkt stimme ich mit Steve Jobs (RiP) überein. Silverlight und Flash haben im Web nichts zu suchen und hatten es auch nie. Flash hatte sich fälschlicherweise fast als ein Standard im Web durchgesetzt. Kein Wunder, war es bis zu Silverlight doch auch die einzige Möglichkeit schnell schöne Rich Internet Applications zu schreiben. Ich habe selber habe (nicht nur fürs Web) Anwendungen mit Flash erstellt.
Silverlight ist eine Alternative zu Flash, die sich zwar als Technologie, aber im Web kaum durchgesetzt hat. (Allerdings: Erst vor ein paar Monaten hat Amazon den Videoplayer für die Filme auf lovefilm.de von Flash auf Silverlight ändern lassen.) Das hat sicher auch einigen klar gemacht, dass beide Technologien ihre Daseinsberechtigungen haben, aber nicht im Web, sprich nicht für alle Benutzer und nicht für alle Endgeräte. Wieso auch…
Dafür gibt es bereits einen Standard und der heißt HTML. ;-)
Jetzt mit HTML5 haben auch die Videoplayer mit Flash oder Silverlight keine Daseinsberechtigung mehr. Und das ist auch gut so, so ist es möglich eine Website mit allen Inhalten, für alle Benutzer und allen Endgeräten zur Verfügung zu stellen. Genial oder? Ich finde es jedenfalls genial…
Und wo hat Flash und Silverlight noch eine Daseinsberechtigung?
Überall dort wo HTML aufhört, bzw. überall dort wo HTML zu aufwendig wäre und überall dort wo die Zielgruppe eingeschränkt ist. In den aktuellen Projekten, an denen ich beteiligt bin, ist die Zielgruppe begrenzt, bzw. den Benutzern kann also die Systemvoraussetzungen genannt werden. Bei allen Projekten handelt es sich um Geschäftsanwendungen.
Und Silverlight 6? Benötigen wir ein Silverlight 6?
Wenn die Tatsache stimmt, dass die XAML-Schicht mit Silverlight 5 und WPF 4.5 identisch sein kann, so wird Silverlight 6 nicht mehr benötigt. Wieso auch? Wir haben dann eine Technologie mit der Bezeichnung XAML mit C#, bzw. XAML mit VB. Basierend auf unterschiedlichen Frameworks. Ehrlich gesagt, finde ich diese Vorstellung gar nicht mal so übel…
Einzig eine Frage die ungeklärt ist, ist das Silverlight-Plug-In… Aber Moment mal… Hat sich Microsoft, nicht selber verpflichtet jedes Produkt mindesten zehn Jahre zu supporten?
Nebenher: Wer glaubt eigentlich wirklich, dass eine Software zehn Jahre lang aktuell bleibt?
Wir können also noch ein paar Jahre XAML mit C# oder VB im Silverlight Plug-In laufen lassen… Und dann ist .NET fast zwanzig Jahre alt… Und dann? Möglicherweise wird das Plug-In dann nicht mehr Silverlight heißen… Möglicherweise auch ganz was anderes…
Ich möchte hier nicht auch noch anfangen zu spekulieren, sondern nur sagen, dass ich mir erst mal keine Sorgen um die Technologie Silverlight mache. Das heißt nicht, dass man nicht dennoch über den Tellerrand schauen sollte um anderes und neues zu lernen. Ganz im Gegenteil… ;-)

Bei
einer Webanwendung, dich gerade in ASP.NET entwickle, bin ich vor kurzem auf eine
große Anzahl von Verbindungsproblemen zwischen Windows Azure (IIS) und SQL Azure gestoßen.
Die Webseite nutzt Windows Azure, AppFabric-Cache und SQL Azure. Alles lag im Rechenzentrum
West-Europa.
Wie haben sich die Probleme geäußert und wann sind sie aufgetreten?
Beim Datenbankzugriff mit dem Entity Framework gab es folgende Exceptions:
-
Invalid attempt to read when no data is present.
-
The underlying provider failed on Open.
-
Calling 'Read' when the data reader is closed is not a valid operation.
-
An error occurred while reading from the store provider's data reader.
-
A connection was successfully established with the server, but then an error occurred
during the pre-login handshake. (provider: TCP Provider, error: 0 - An existing connection
was forcibly closed by the remote host.)
-
A transport-level error has occurred when receiving results from the server. (provider:
TCP Provider, error: 0 - The semaphore timeout period has expired.)
Die Fehler sind sind aufgetreten, sobald die Webseite etwas stärker belastet wurde.
Dies geschah immer dann, wenn die Webseite durch einen Bot (z.B. Google oder Bing)
gecrawlt wurde. Eigentlich sollten solche geringen Lastschwankungen Windows Azure
bzw. SQL Azure nicht weiter beeindrucken - dachte ich.
Mein erster Versuch die Fehler zu beheben, war die Größe der VM Instanz zu erhöhen.
Leider brachte dies keine Besserung.
An meinem Code konnten diese Fehler nicht liegen, da die Webseite vor dem Umzug zu
Azure schon einige Monate auf meinem eigenen Server fehlerfrei lief.
Ich schilderte diese Probleme dem Azure Support und war von der Antwort sehr überrascht.
Der Support wusste von dem Problem und hatte auch einen Namen dafür parat: “Transient
Conditions”. Ich wurde auf einen Artikel vom
“Windows Azure Customer Advisory Team” hingewiesen, in dem folgendes zu lesen ist:
The database connections may also be dropped due to the variety of reasons
related to network connectivity between the client and distant Microsoft data centers:
quality of network, intermittent network faults in the client’s LAN or WAN infrastructure
and other transient technical reasons.
Als Lösung wird der Einsatz des so genannten Transient
Fault Handling Framework vorgeschlagen, das im wesentlichen nichts weiter macht,
als den Datenbankzugriff zu überwachen. Im Fehlerfall wird der Datenbankzugriff einfach
erneut versucht.
Ich habe mich aus mehreren Gründen gegen den Einsatz dieses Frameworks entschieden:
-
das Framework ist riesengroß und hat einige Abhängigkeiten
-
es ist schlecht dokumentiert
-
ich sehe nicht ein, Infrastruktur-Fehler im Code auszugleichen, wodurch die Ladegeschwindigkeit
der Webseite sinken würde
Gerade zum letzten Punkt, der Performance, habe ich einige Versuche gemacht.
30 bis 50 Versuche um Daten zu lesen waren im Fehlerfall keine Seltenheit und das,
obwohl Datenbank und IIS im selben Azure – Rechenzentrum (West-Europa) lagen. Die
Performance der Webseite würde mit dieser Strategie deutlich in die Knie gehen.
Als nächstes habe ich versucht herauszufinden, ob man die Verbindungsprobleme nicht
anders in den Griff bekommen kann.
Ich habe die Webseite wieder auf meinem eigenen Webserver gelegt, aber die Datenbank
bei Azure gelassen, schon waren die Fehler weg!
Auch wenn die Webseite im Rechenzentrum Europa Nord liegt und die Datenbank in Europa
West, gibt es keine Probleme. In dieser Konstellation läuft die Webseite jetzt einen
Monat fehlerfrei.
Bin ich mit meinen Erfahrungen ein Einzelfall (Ich habe ja öfter mal Pech mit Server-Hardware),
oder hat Microsoft hier noch massive Probleme?
So geht es manchmal:
- Da arbeitet man 4, 8, 12 oder 16 Stunden an einem Modul.
- Alles sieht gut aus, nicht mehr lange und wir können einchecken.
- Du änderst noch dies und das, steckst noch mal 2 Stunden Arbeit rein weil noch was optimiert werden soll und auf einmal merkst Du dass Du Dich verrannt hast. Die letzten 2 Stunden Arbeit hattest Du irgendwie das Gehirn nicht eingeschaltet, x-Änderungen gemacht, die nun alle Sch…sind.
- Undo ist nicht mehr, weil Du schon andere Projekte offen hattest bzw. einmal VS abgeraucht ist.
- Du hast Bockmist gebaut und jetzt willst Du auf den Stand von vor 4 Stunden zurück, oder den von gestern Abend.
- Ein Shelveset hast Du im TFS nicht angelegt. Das machst Du nur wenn Du ins Wochenende gehst, oder Deinen Kollegen was weiterreichen musst.
Was nun?
Als VA-X Benutzer (VisualAssist X http://www.wholetomato.com) hat man tatsächlich noch ein Backup!
Und zwar nicht nur eines, sondern ein paar.
In meinem History Ordner von VA-X
C:\Users\USER\AppData\Local\Microsoft\VisualStudio\10.0\Extensions\Whole Tomato Software\Visual Assist X\VERSION\Data\vs10\history\
werde ich fündig…

Ufff…
Ich habe dieses Backup mittlerweile schon so oft verwendet, dass ich dazu übergangen bin diesen Ordner umzulegen an eine Stelle an die ich schneller dran komme. Das geht über den Registry Schlüssel HKCU\Software\Whole Tomato\UserDataDir.
Wer mehr dazu wissen will findet hier weitere Infos:
http://www.wholetomato.com/forum/topic.asp?TOPIC_ID=6865
Nachtrag (30.01.2012):
Damit diese Funktion auch verfügbar ist muss im VA-X die Auto Recovery Option eingeschaltet sein.
VA-X -> Options -> Performance -> Enable Auto Recovery
Copyright © 2010 Martin Richter
Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.
(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)
Der Schweizer MVP Christian Moser hat eine umfassende Website zum Thema Windows Presentation Foundation (WPF) für Einsteiger zusammengestellt. Wer in einer Woche den Einstieg machen will, sollte sich insbesondere der Eintrag Learn WPF in one Week anschauen.

Das umfassende Online-Werk eignet sich auch für Entwickler, die schon länger in anderen Themenbereichen unterwegs waren, zur schnellen und knackigen Wissensauffrischung. Auch Einsteiger in die Programmierung für Windows Phone finden hier klare, einfach verständliche Worte und Zusammenhänge, hieß doch die Oberflächen-Basistechnologie in ihrem Entwicklungsstadium als WPF-Untermenge noch WPF/E ("Windows Presentation Foundation for Everywhere").
Links:
Was bisher geschah: TDD im Flow – Teil 1 Test #2: Ein Worker entnimmt aus mehreren Queues Der dritte Test in meiner Planung bleibt sinnig. Er führt zu Änderungen am Produktionscode. Den Testcode zu zeigen, lohnt nicht. Er entspricht der Skizze im Bild. Aber hier der Produktionscode: internal class NotifyingMultiQueue{ List>> _queues = new List<
Nach ca. 10 Monaten im Release Candidate (RC) Status ist System Center Advisor (ehemals Codename Microsoft Atlanta) seit gestern öffentlich verfügbar. Eine Information dazu findet sich im Microsoft Server and Cloud Platform Blog und im CSS SQL Server Engineers Blog. Der auf Windows Azure gehostete Cloud Service ermöglicht proaktives Server Configuration Management für SQL Server [...]
Im letzten Teil meiner Serie zu Knockout.js beschäftigen wir uns mit dem Mapping Plugin. In einigen der letzten Beispiele wurde mit JSON gearbeitet und so Daten simuliert, die vom Server stammen. Damit diese an eine View gebunden wurde, musste das ViewModel (welches Observables enthält) manuell aufgefüllt werden. Das Mapping Plugin bietet hier eine Unterstützung, die in diesem Anwendungsfall sehr viel Aufwand spart. Dieser Artikel zeigt wie es funktioniert.
Voraussetzungen
Damit das Mapping-Plugin verwendet werden kann, muss es via github bezogen werden. Hier der Direktlink zur aktuellsten Version. Das Script ist dann natürlich entsprechend einzubinden.
Grundlagen / Wiederholung
In den letzten Teilen dieser Serie wurden alle ViewModels manuell erstellt und sahen - mehr oder weniger - so aus:
var MyViewModel = function() {
this.title = ko.observable();
this.author = ko.observable();
this.pages = ko.observable();
}
Die Daten wurden dann so gesetzt:
myViewModel.title('Ein Buch');
myViewModel.author('Ein Autor');
myViewModel.pages(500);
So musste das für jede Variable vorgenommen werden. Ein recht großer Aufwand, vor allem, wenn die Struktur komplexer wird.
Knockout.mapping kann diesen Aufwand für uns stark minimieren.
Beispiel
Nun aber zu einem Beispiel an Hand dessen wir uns ansehen, wie knockout.mapping funktioniert. Dazu benötigen wir eine View, die mit einer Schaltfläche ausgestattet ist. Bei einem Klick darauf werden JSON-Daten vom Server geladen und an die View gebunden. Hier vorerst die View:
<div id="control">
<input type="button" data-bind="click: loadData" value="Load data"></input>
</div>
<div id="data">
<h2>Loaded Data</h2>
<p>
<span data-bind="text: userName"></span><br/>
<span data-bind="text: tweetCount"></span>
</p>
</div>
Soweit noch nichts Neues, aber wenden wir uns der JavaScript-Seite zu.
$(function(){
var OverallViewModel = function() {
this.loadData = function() {
$.getJSON('http://dl.dropbox.com/u/30654117/Demos/JavaScript/Knockout.js/Mapping/data/data.json', function(data) {
var viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel, document.getElementById('data'));
});
};
}
var firstViewModel = new OverallViewModel();
ko.applyBindings(firstViewModel, document.getElementById('control'));
});
Hier wird ein ViewModel namens OverallViewModel definiert und an das DIV mit der Id control gebunden. Darin enthalten ist die Funktion loadData, welche bei einem Klick auf die Schaltfläche ausgelöst wird.
Darin wird im ersten Schritt das JSON vom Server bezogen. Im Anschluss wird ko.mapping.fromJS mit den Daten als Parameter aufgerufen. Das Ergebnis ist ein ViewModel, welches die entsprechenden Eigenschaften, welche im JSON definiert sind (als Observables) besitzt.
Der Vollständigkeit halber hier das JSON:
{
"userName": "Norbert Eder",
"tweetCount": 10000
}
Das resultierende ViewModel wird nun via ko.applyBindings an das DIV mit der Id data gebunden und die Daten kommen sofort zur Anzeige. Das einfache Beispiel ist fertig. Aber das Plugin kann noch mehr.
Ins Mapping eingreifen
Meine erste Frage - und das wird vermutlich jedem so gehen, war:
So ein einfaches ViewModel ist ganz nett, aber was, wenn ich Funktionen, berechnete Eigenschaften etc. benötige?
Aber auch hierfür gibt es eine entsprechende Lösung.
Erweitern wir obiges Beispiel ein wenig. Zu den rudimentären Tweet-Informationen sollen nun einzelne Tweets hinzugefügt und angezeigt werden. Jeder Eintrag soll mit einer Schaltfläche bestückt werden, mit deren Hilfe ein Retweet durchgeführt werden kann. Auch das sollte nun recht einfach gehen, haben wir uns doch bereits mit Templates beschäftigt. Die Herausforderung ist jedoch, die Tweets mit einem eigenen ViewModel zu versehen, welches eine entsprechende Funktion retweet anbietet, um eben diese Aktion ausführen zu können.
Zuerst aber ein Blick auf die Daten, zwecks Übersicht der durchgeführten Änderungen:
{
"userName": "Norbert Eder",
"tweetCount": 10000,
"tweets": [
{
"content": "Ein Testtweet der mit Sicherheit 140 Zeichen nicht überschreitet."
},
{
"content": "Knockout.js ist schon eine sehr feine Sache!"
},
{
"content": "Bin schon gespannt auf Backbone.js. Soll auch nett sein."
}
]
}
Nun muss die View umgebaut und mit einem Template versehen werden, auch noch nicht spektakulär:
<div id="control2">
<input type="button" data-bind="click: loadData" value="Load data"></input>
</div>
<div id="data2">
<h2>Loaded Data</h2>
<p>
<span data-bind="text: userName"></span><br/>
<span data-bind="text: tweetCount"></span>
</p>
<div data-bind="template: { name: 'tweet-template', foreach: tweets }"></div>
</div>
<script type="text/html" id="tweet-template">
<p data-bind="text: content"/>
<input type="button" value="Retweet" data-bind="click: retweet"/></input>
</script>
Interessant ist das ViewModel, oder besser gesagt, sind die beiden ViewModels, da für die Anzeige eines einzelnen Tweets ein weiteres ViewModel (nennen wir es TweetViewModel) definiert werden muss. Immerhin möchten wir eine Funktion unterbringen. Darin sehen wir nun auch bereits den ersten Trick:
var TweetViewModel = function(data) {
ko.mapping.fromJS(data, {}, this);
this.retweet = function() {
alert("retweeted");
};
}
Die Funktion retweet ist einfach und zeigt hier lediglich einen Alert an. Zumindest kann so die Funktionalität getestet werden. Interessanter ist, dass das ViewModel Daten als Parameter übergeben bekommt und diese via ko.mapping.fromJS auf sich selbst appliziert. Damit werden für die in den Daten enthaltenen Eigenschaften korrespondierende Observables am ViewModel erzeugt. Erster Teil erledigt.
Nun muss noch ein Weg gefunden werden, eine Instanz von TweetViewModel pro Item zu erzeugen. Dazu muss das Haupt-ViewModel ein wenig adaptiert werden.
Hinweis: Dieses wurde mit einem anderen Namen als im einfachen Beispiel zu sehen, da es im gleichen Beispiel zu finden ist, Download siehe weiter unten.
Sehen wir es uns an:
var AnotherViewModel = function() {
this.loadData = function() {
$.getJSON('http://dl.dropbox.com/u/30654117/Demos/JavaScript/Knockout.js/Mapping/data/data2.json', function(data) {
var viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(viewModel, document.getElementById('data2'));
});
};
}
Abgesehen davon, dass die Daten nun von einer anderen Quelle bezogen werden, sticht diese Änderung ins Auge:
var viewModel = ko.mapping.fromJS(data, mapping);
Es wird ein neuer Parameter übergeben. Eine Konfiguration für das Mapping.
var mapping = {
'tweets': {
create: function(options) {
return new TweetViewModel(options.data);
}
}
}
Darin wird ein create-Callback definiert, der sich auf das Array tweets bezieht (siehe Daten weiter oben) und für alle Einträge aus dem tweets-Array (siehe Daten) aufgerufen. Als Parameter werden options übergeben. Diese enthalten:
- data: Ein JavaScript-Objekt mit den Daten
- parent: Das Eltern-Objekt oder das Array zu dem die Daten gehören
Schlussendlich definiert die Zeile
return new TweetViewModel(options.data);
dass eine neue Instanz von TweetViewModel instanziiert werden soll. Die Daten werden als Parameter übergeben und innerhalb des ViewModel weiterverarbeitet (siehe weiter oben).
Das wunderschön gestaltete Ergebnis:

Fazit
Diese beiden Beispiele zeigen sehr schön, dass man sich mit Hilfe des Mapping Plugins jede Menge Schreibarbeit - und damit durchaus auch Fehler - sparen kann. Durch das mögliche Eingreifen in die Erstellung der ViewModels sind alle notwendigen Szenarien vorstellbar und keine Grenzen gesetzt.
Download / Showcase
Getestet werden können die beschriebenen Beispiele hier. Gleich untenstehend der Download des gesamten Paketes:
Feedback
Gerne nehme ich jegliches Feedback zu diesem Beitrag, als auch zur gesamten Serie zu Knockout.js entgegen. Hat dir die Serie geholfen? Hast du Anmerkungen, Anregungen? Fehlt ein Teil, sprich, wurde ein wichtiges Thema nicht besprochen? Teile es mir doch einfach mit und verfasse gleich einen Kommentar.
Jetzt Knockout.js lernen: Die Serie
Mit einem Überblick über die Arbeiten an den ALM-Möglichkeiten der kommenden Entwicklungsumgebung Visual Studio 11 gibt Microsofts Entwicklerabteilungschef Sivaramakrishnan "Soma" Somasegar in seinem Blog einen umfassend bebilderten Einblick in die Visual Studio 11 Developer Preview, und verspricht frühe Nachricht zum Stand des aktuellen Fortschritts an unseren Werkzeugen von morgen. In dem angebotenen Überblick stehen die mit der Preview-Version schon heute evaluierbaren Aspekte Team-Zusammenarbeit, agile Prozesse, Projektmanagement und Feedbackmechanismen, ergänzt um hilfreiche Ressourcen der vergangenen Wochen und Monate zur näheren Einarbeitung in einzelne Details.
PLUS: Soeben wurde das aktuellste englische Visual Studio 11 Developer Preview Training Kit veröffentlicht.
Um eine einfache Trainingsmöglichkeit für den Team Foundation Server 2010 zu bieten werden im msdn Virtual Lab 3 Szenarien zum Team Foundation Server (engl.) als hands-on Lab angeboten. Die virtuellen Labs erfordern keinen großen Download sondern nur en Active-X control im Browser.
Wie bekommt man Daten aus einem lokalen SQL Server in SQL Azure? Mit Tools, wie dem SQL Azure Migration Wizard oder mit dem nigel-nagel-neuen SQL Azure Import/Export Service.

Wie das Windows Azure MSDN Blog verkündet, ging das SQL Azure Import/Export Service heute in den Produktivbetrieb. Der Name ist etwas sperrig – aber beschreibt genau die Funktion.
Announcing SQL Azure Import/Export Service Now in Production
Einige Highlights des Services:
- Verbesserte Leistung
- Verbesserte Connectivity
- Selektiver Export (Neu)
- Fortschritts-Anzeige (Neu)
- Das Service ist nun von CTP in Produktion
- Neue sample EXE
Weitere Details und Beispiel-Videos gibt es im Blog von DAC Guy:
SQL Azure Import/Export Service has hit Production
Das SQL Azure Import/Export Service steht allen Windows Azure Kunden kostenfrei zur Verfügung.
In 10 kostenlosen, deutschsprachigen Hands-on-Lab-Handbüchern für SharePoint 2010 werden die ersten Schritte zur SharePoint 2010-Entwicklung beschrieben. Jedes Lab ist dabei für die Sprachen C# und Visual Basic verfügbar.
Zum Download Center
Das eigentlich für 24.02.2012 mit Steffen geplante Event zu F# wird verschoben.
Einen neuen Termin geben wir an derselben
Stelle bekannt und auf der Startseite der .NET User Group Leipzig dotnet-leipzig.de.
Team Foundation Service ist der TFS in der Cloud. Keine Installation, Ideal für verteilte kleine Teams, ob Scrum, MSF Agile oder CMMI es ist Euer Prozess Ihr könnt wählen. Freunden könnt Ihr ganz einfach Zugriff via Windows Live ID geben und schon geht’s los.
Jetzt unter http://tfspreview.com mit folgendem Code anmelden : “TfsDecUpdate”
Viel Spassss
Steht Flow-Design eigentlich im Gegensatz zu Test-Driven Design? Nein. Zwar bin ich überzeugt, dass TDD viel weniger wichtig ist, als viele Vertreter agiler Softwareentwicklung glauben, aber deshalb hat TDD doch seinen Platz. An einem Beispiel möchte ich das demonstrieren. Vor einiger Zeit habe ich Gedanken zu einer Flow Execution Engine geäußert. Die habe ich inzwischen angefangen zu bauen. Ihr
Heute möchte ich zeigen, wie man sich einen einfachen Style-Switcher mittels jQuery in einem MVC / Razor Projekt einbauen kann.

Den Basis-Style setzen wir zu Beginn, wenn die Seite zum ersten Mal geöffnet wird. Wichtig ist, das wir eine Id setzen, um in unserer jQuery Funktion dieses Element wieder zu finden.
<link id="jQ" href="@Url.Content("http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css")" rel="Stylesheet" type="text/css" />
Um zwischen den Styles zu wechseln, erstellen wir eine Html-ComboBox mit den Namen der einzelnen Styles:
<select id="styles">
<option value="base">base</option>
<option value="black-tie">black-tie</option>
<option value="blitzer">blitzer</option>
<option value="cupertino">cupertino</option>
<option value="dark-hive">dark-hive</option>
<option value="dot-luv">dot-luv</option>
<option value="eggplant">eggplant</option>
<option value="excite-bike">excite-bike</option>
<option value="flick">flick</option>
<option value="hot-sneaks">hot-sneaks</option>
<option value="humanity">humanity</option>
<option value="le-frog">le-frog</option>
<option value="mint-choc">mint-chocolate</option>
<option value="overcast">overcast</option>
<option value="pepper-grinder">pepper-grinder</option>
<option value="redmond">redmond</option>
<option value="smoothness">smoothness</option>
<option value="south-street">south-street</option>
<option value="start">start</option>
<option value="sunny">sunny</option>
<option value="swanky-purse">swanky-purse</option>
<option value="trontastic">trontastic</option>
<option value="ui-darkness">ui-darkness</option>
<option value="ui-lightness">ui-lightness</option>
<option value="vader">vader</option>
</select>
Als Script verwenden wir folgenden Codeabschnitt. Die Funktion setzt den gewählten Style und ruft eine Methode im Controller auf, der ggfls. den Style in den Usereinstellungen speichern kann.
<script>
$(document).ready(function ()
$('#styles').change(function () {
var style = $(this).val();
$("#jQ").attr("href", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/" + style + "/jquery-ui.css");
$.post('@Url.Action("SaveStyle", "Home")', { style: style }, function () {
return false;
});
});
});
</script>
Im Controller dann kann der Name des gewählten Styles weiter verarbeitet werden:
public void SaveStyle(string style)
{
//save style
}
Viel Spaß beim entwickeln : )
Dieser Beitrag stammt von Mario Priebe.

Ähnliche Beiträge
Heute bin ich wieder mal (jedes mal wenn ich das Management Studio neu installiere) über ein bereits seit langem bekanntes Problem gestolpert.
Nachdem ich einer vorhandenen Tabelle einige Felder über den Table Designer hinzugefügt habe und diese Änderungen speichern wollte, habe ich folgende Meldung erhalten:

Verzeihung liebes Management Studio, Nein ich möchte nicht dass du die Tabelle löschst und sie mit der neuen Struktur Neu erstellst.
Da mir aber zu diesem Zeitpunkt wieder mal entfallen war, dass ich dieses Problem früher schon hatte, habe ich mich kurzerhand an meine Timeline in Twitter gewandt.
Dort habe ich prompt, wie fast immer, die richtige Antwort erhalten.
Danke dafür an Sebastian und Norbert, bei den beiden Funktioniert das Gedächtnis wohl noch besser als bei mir.
Und damit ich in Zukunft selbst daran denke, und auch Uwe nachschauen kann wie man das Problem lösen kann, habe ich diesen Beitrag geschrieben.
Und hier nun die Lösung des Problems:
Man kann in den Optionen einstellen, ob das Management Studio diese Vorgehensweise “Warnung ausgeben und das Drop/Create Szenario” anstelle einer “Änderung der Tabellenstruktur”, verwenden soll (Siehe nachfolgende Abbildung).

Vielleicht hilft das hier nicht nur mir und Uwe
Ein Überblick über die kommenden .NET-Konferenzen in Deutschland im Jahr 2012.
C++ ist noch lange nicht tod! Microsoft hat in den letzten Jahren wieder mehr Resourcen in diesen Bereich investiert. Um wieder mehr auf diesen Bereich aufmerksam zu machen bzw. sich mal weider zu Informieren, was es alles gibt, solltest Du unbedingt auf einen der C++ Days gehen. Das beste dabei ist, das Ganze ist kostenlos! Also, gleich Anmelden:
2.2.2012 14:00- 18:00 Berlin (ausgebucht)
- 7.2.2012 14:00- 18:00 Bad Homburg (noch freie Plätze!)
- 13.2.2012 14:00- 18:00 Karlsruhe (noch freie Plätze!)
5.3.2012 14:00- 18:00 Köln (ausgebucht)
Mehr Infos unter:
http://blogs.msdn.com/b/cbinder/archive/2011/12/29/c-entwickler-uptodate-microsoft-c-day-2012.aspx
In meinem Neujahrspost habe ich schon angedeutet, dass ich dieses Jahr wohl viel unterwegs sein werde und so steht jetzt fest, dass ich im Mai auf der .Net Dev Con zu MS Test sprechen werde.

Dort werde ich unter dem Titel: “MS Test - der missverstandene Stiefbruder” im Grunde das auseinander nehmen, was ich die letzten zwei Jahre im Umgang mit der Visual Studio Test Integration und weitestgehend freien Alternativen erlebt habe. Genauer geht es mir dabei um die Lücke zwischen Unit Tests mit NUnit, Moq und Resharper, gegenüber den System- und Integrationstests mit Visual Studio, samt Pex und Moles.
Ich habe dabei nicht vor auf irgend welchen Designschwächen von was auch immer welchen Tools herum zu hacken. Viel mehr geht es mir darum die unterschiedlichen Sichtweisen gegenüber zu stellen die hinter den einzelnen Frameworks stehen, deren wichtigste Features zu erläutern und die Gründe zu nennen warum sie verwendet werden. Ob sie ihre Arbeit gut machen muss dann jeder selbst entscheiden.
Ich hoffe also auf eine rege Teilnahme und freue mich auf jeden den ich am 15. Mai willkommen heißen darf.
In Jetzt Knockout.js lernen: Observables erweitern der Serie zu Knockout.js wurde gezeigt, wie Observables erweitert werden können. Als Beispiel diente eine Validierung auf Basis von einzelnen Observables. Nun hängen diese in der Regel aber in einem Formular zusammen, wodurch eine Gesamtvalidierung und eine damit verbundene Freischaltung von Schaltflächen bzw. weiteren Interaktionsmöglichkeiten einhergeht. Dieser Beitrag greift das Validierungsbeispiel auf und erweitert es im Rahmen dieser Anforderung.
Ausgangspunkt
Den Ausgangspunkt dieses Beitrags bietet dieses Beispiel, zu dem Florian einen sinnvollen Erweiterungswunsch hinterlassen hat:
Interessant wäre noch ein Save-Button, der nur aktiv ist, wenn es keine Fehler auf dem gesamten Formular mehr gibt, sowie ein Cancel- bzw. Undo-Button der bei eventuellen Fehlern, die Werte zurücksetzt auf den ursprünglichen Wert.
Aus meiner Sicht handelt es sich hierbei um eine gängige Anforderung, die ich natürlich aufgegriffen habe. Wer den Hintergrund des Beispiels erfahren möchte, kann dies hier vollständig nachlesen. Als Zusammenfassung: Das Beispiel zeigt, wie ein eigener Extender für Observables unter Knockout.js geschrieben werden kann, um einzelne Observables zu validieren. Als Validierung wurde eine Erweiterung hinsichtlich Pflichtfelder implementiert. Eine Gesamtvalidierung war nicht vorgesehen.
Gesamtvalidierung
Aktuell wird jedes Observable einzeln validiert. Entsprechend der Anforderung sollen nun zwei Schaltflächen für das Speichern, als auch das Zurückstellen auf die zuletzt gültigen Werte (im Fehlerfalle) hinzugekommen. Damit diese auch entsprechend freigeschalten sind, muss das ViewModel bekannt geben, in welchem Status es sich gesamt befindet. Dieser ergibt sich aus den Status jedes einzelnen Observables. Dies können wir uns berechnen lassen (ko.computed) und nennen wir hasErrors.
self.hasErrors = ko.computed(function()
{
return self.title.hasError() ||
self.author.hasError() ||
self.pages.hasError();
});
Hinweis: self ist eine Referenz auf this und wurde im Vergleich zum originalen Beispiel hinzugefügt, um innerhalb der anonymen Funktion auf die Eigenschaften und Funktionen des ViewModels zugreifen zu können.
Damit könnten nun auch bereits die beiden neuen Schaltflächen gesteuert werden:
<input type="button" value="Save" data-bind="disable: hasErrors"></input>
<input type="button" value="Undo" data-bind="enable: hasErrors"></input>
Auf die Speichern-Schaltfläche möchte ich an dieser Stelle nicht weiter eingehen, viel spannender ist hier der Undo-Button. Dieser soll ja - im Fehlerfalle - die zuletzt gültigen Werte hinterlegen. Dies bedeutet, dass diese erfasst werden müssen.
Nun ist es so, dass die einzelnen Eingabefelder eine value-Bindung besitzen und das Durchschreiben der Werte via valueUpdate auf den Wert afterkeydown gesetzt wurde. Das ViewModel wird also in Echtzeit aktualisiert. Darauf können wir also nicht aufbauen, da der Benutzer beispielsweise per Backspace alle Zeichen von “Beispiel” löschen könnte, durch die Echtzeit-Aktualisierung würde der zuletzt valide Wert durch “B” repräsentiert. Worauf wir uns jedoch hängen können ist das Verlassen des Fokus, also dem OnBlur-Ereignis.
Dazu brauchen wir eine Funktion, die uns den beim Verlassen vorhandenen - gültigen - Wert übernimmt:
self.updateLastValidValue = function(observable) {
if (!observable.hasError()) {
observable.lastValidValue(observable());
}
};
Als Parameter wird das an das Eingabefeld gebundene Observable übergeben. So kann auch auf die durch den Extender geschriebenen Eigenschaften (siehe hasError) zugegriffen werden. Läuft die Validierung ohne Fehler, dann ist ein entsprechender Wert vorhanden und kann übernommen werden. Hierzu wird eine neue Eigenschaft namens lastValidValue mit dem Wert gesetzt.
Damit dies nun bei allen Eingabefeldern berücksichtigt wird, ist deren Bindung zu aktualisieren, hier an Hand der Titel-Eingabe:
<input data-bind='value: title, valueUpdate: "afterkeydown", event: { blur: function() { updateLastValidValue(title); }}' />
So werden die Werte nun weiterhin in Echtzeit übernommen und zusätzlich beim Verlassen des Feldes die Funktion updateLastValidValue des ViewModels aufgerufen. Das ist allerdings noch nicht alles, denn ein etwaiger initial gesetzter Wert würde nicht berücksichtig werden. An dieser Stelle bietet es sich an, den bereits existierenden Extender (requireField) zu erweitern:
ko.extenders.requiredField = function(target, message) {
target.hasError = ko.observable();
target.validationMessage = ko.observable();
target.lastValidValue = ko.observable();
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : message || "* required");
}
function setInitialValueIfValid() {
if (!target.hasError()) {
target.lastValidValue(target());
}
}
validate(target());
setInitialValueIfValid();
target.subscribe(validate);
return target;
};
Neu ist die Funktion setInitialValueIfValid(). Diese wird beim Erstellen von requiredField durchlaufen (siehe den Aufruf direkt nach der initialen Validierung) und, wenn ein Wert vorhanden ist, lastValidValue mit dem entsprechenden Wert beschrieben.
Zu guter Letzt fehlt noch das tatsächliche Zurückschreiben der Werte, wenn die Undo-Schaltfläche geklickt wird. Dazu benötigen wir eine Funktion, nennen wir sie resetToValidValues:
self.resetToValidValues = function() {
self.title(self.title.lastValidValue());
self.author(self.author.lastValidValue());
self.pages(self.pages.lastValidValue());
};
Außerdem muss die click-Bindung auf der Schaltfläche gesetzt werden:
<input type="button" value="Undo" data-bind="enable: hasErrors, click: resetToValidValues"></input>
Fertig ist die Gesamtvalidierung des Formulars, inklusive der Möglichkeit, die zuletzt gültigen Werte zurück zu schreiben.
Ergebnis
An dieser Stelle nun zwei Screenshots, die die Implementierung visuell veranschaulichen. Der erste Screenshot zeigt das gesamte Formular ohne Validierungsfehler:

Und hier nun im Fehlerfalle:

Download / Showcase
Wie immer gibt es auch dieses Beispiel vollständig für eigene Tests. Unter http://jsfiddle.net/VgvuK/ findet sich die entsprechende Spielwiese. Wer möchte, kann sich dies auch unterhalb ansehen, sollte hierbei allerdings auf die Nutzung eines IE verzichten:
Fazit
Die notwendigen Erweiterungen der “Feld-Validierung” konnte in meinen Augen mit sehr wenig Aufwand auf eine Gesamtvalidierung erweitert werden, wodurch für den Benutzer sehr schnell ersichtlich ist, welche Aktionen zur Verfügung stellen. Ein äußerst sauberer Weg, durch die mögliche Auftrennung.
Feedback
Gerne nehme ich - wie immer - konstruktive Kritik, Anregungen und Anmerkungen entgegen. Einfach einen kurzen Kommentar hinterlassen, es findet sich sicherlich die eine oder andere Verbesserungsmöglichkeit.
Jetzt Knockout.js lernen: Die Serie
Soo, nachdem ich die Überschrift mit all den hippen Begriffen vollgepackt habe die es in Sachen Web momentan so gibt möchte ich euch kurz erklären worum es in diesem Artikel gehen soll.
Ihr werdet sicher mitbekommen haben, dass HTML5 auf dem Vormarsch ist und auch wenn es immer noch nicht offiziell fertig ist findet man immer häufiger den HTML5-Header <!DOCTYPE html> auf diversen Seiten.
Eins der meiner Meinung nach nützlichsten Features die wir mit HTML5 erhalten sind die neuen Input-Typen. Denn bisher hatten wir keine Wahl und mussten type="text" benutzen!
Die Eingabefelder vom Typ Text konnten natürlich alles enthalten, sind aber nicht gerade Benutzerfreundlich wenn man etwas komplexere Daten eingeben soll wie zum Beispiel ein Datum.
In HTML5 wurden deswegen spezifische Typen für solche immer wieder einkehrende Eingaben eingeführt. Eine von ihnen ist "Date":
Birthday: <input type="date" name="bday" />
Der große Vorteil hier ist, dass die Browser nun eine eigene Implementierung für diesen Typ von Eingabefeldern machen können. Falls der Browser nun also diesen neuen Eingabe Typ unterstützt blendet er automatisch einem (mehr oder weniger) schönen Date-Picker ein in dem man bequem das Datum wählen kann:

Ansicht des neuen Typen in verschiedenen Browsern
Ein weiterer großer Vorteil ist, dass auch die mobilen Browser wie z.B. auf dem iPhone diese neuen Elemente ebenfalls unterstützen und einen passenden Picker einblenden:

Date-Picker auf dem iPhone
Wie ihr in dem ersten Screenshot sehen könnt unterstützt der FireFox (zumindest zum Zeitpunkt des Screenshots) den neuen Typ nicht. In diesem Fall blendet er ein gewöhnliches Textfeld ein wo wir nun gezwungen sind das Datum auf die gewohnte (unbequeme) Weise einzutragen.
Übrigens, ich glaube ich muss euch nicht sagen warum der Internet Explorer hier nicht mit aufgeführt ist oder?
Und genau das ist das Problem um das es in diesem Blogpost geht. Wenn wir die tollen neuen Elemente nutzen gehen wir das Risiko ein, dass Nutzer die einen älteren Browser nutzen nicht in den Genuss einer bequemen Eingabe kommen.

jQuery Date-Picker
Wir könnten auch komplett auf das HTML5 Element verzichten und direkt alles mit jQuery machen, welches auch einen Date-Picker bietet, aber das ist auch nicht das gelbe vom Ei, denn dann wären die Mobilen Nutzer in Nachteil, da dort die Browser diese Elemente für gewöhnlich unterstützen und eine gewohnte Oberfläche für die Eingabe bieten.
Die Optimale Lösung ist offensichtlich eine Mischung beider Welten. Wenn der Benutzer die Seite mit einem kompatiblen Browser aufruft soll der Date-Picker des Browsers genutzt werden, wenn der Browser aber veraltet ist soll stattdessen der jQuery Fallback greifen und der JavaScript Date-Picker (siehe links) genutzt werden.
Zu unserem Glück macht uns ASP.NET MVC die Umsetzung dieses Plans sehr leicht, da es an den nötigen Stellen sehr einfach erweitert werden kann.
Schauen wir uns mal ein kleines Beispiel an. Wir haben eine Klasse Person, und wollen auch dessen Geburtstag speichern, hier wollen wir die tolle neue Funktionalität nutzen. Implementieren wir das Ganze jedoch erstmal wie gewohnt:
public class Person
{
public int ID { get; set; }
public String Name { get; set; }
public DateTime Geburtstag { get; set; }
}
Wenn wir die Model-Klasse haben können wir das MVC Scaffolding nutzen um für uns eine View zum Erstellen neuer Personen anzulegen:

MVC Scaffolding kommt uns zu Hilfe
Schauen wir uns nun doch mal an was da für uns tolles generiert wurde:
<div class="editor-field">
@Html.EditorFor(model => model.Geburtstag)
@Html.ValidationMessageFor(model => model.Geburtstag)
</div>
Auffällig hierbei ist, dass hier @Html.EditorFor genutzt wird und nicht etwa @Html.TextBoxFor! Der Hintergrund ist der, dass MVC bei der Generierung versuchen wird ein passendes Element für den angegebenen Datentyp (DateTime) zu bestimmen, aber da MVC standardmäßig nur den Typ Text kennt wird hier eigentlich immer ein Input-Element vom Typ text generiert.
Hier kommt uns die Erweiterbarkeit von MVC zu gute, denn wir können ganz einfach NuGet nutzen um uns die nötige Funktionalität zu verschaffen. Wir installieren das Packet MvcHtml5Templates.

Installation über NuGet

Neue Templates
Nachdem NuGet alles erledigt hat werdet ihr feststellen, dass ihr ein paar neue Dateien in eurem Views/Shared Verzeichnis habt (siehe Bild links). Und wie ihr schon an dem Namen erkennen könnt sind das die neuen Input-Typen aus HTML5.
Diese Templates machen im Grunde nichts anderes als die MVC-Eigenen zu überschreiben und versehen die mit dem passendem Type-Attribut.
Hier sind euch keine Grenzen gesetzt ihr könnt natürlich auch eire eigenen Templates definieren mit euren eigenen Typen. (Auch wenn man das eher selten benötigt)
Das Tolle: mehr müssen wir nicht machen. MVC wird nun zur Laufzeit statt einem Text ein Date Input-Element für uns anlegen. Beachtet, dass das nur geht wenn wir in der View die allgemeine Funktion @Html.EditorFor nutzen und keinen Spezifischen Typ angeben.
Schauen wir mal in den Sourcecode der zur Laufzeit für das Geburtstagsfeld generiert wird:
<input class="text-box single-line"
data-val="true"
data-val-required="Das Feld 'Geburtstag' ist erforderlich"
id="Geburtstag"
name="Geburtstag"
type="datetime"
value=""; />
Wie ihr seht wird nun der Korrekte Typ, nämlich datetime verwendet. Wenn wir die Seite nun also mit einem kompatiblen Browser aufrufen können wir ganz bequem das Datum wählen.
Leider ist der Opera Browser momentan wohl der einzige Desktop Browser der uns hier einen Benutzerfreundlichen Dialog einblendet (siehe erstes Bild oben), somit müssen wir dafür sorgen, dass die Benutzer mit anderen oder alten Browsern nicht benachteiligt werden.

JavaScript Magie
Auch für diese Problematik bringt MVC bereits alles mit was nötig ist sie zu lösen. Werfen wir doch mal einen Blick in unseren Scripts Ordner finden wir alle nötigen jQuery und jQuery UI Skripte, dazu kommt noch die modernizr Bibliothek die uns auch zu Gute kommen wird.
Die jQuery Bibliotheken liefern und die nötige Funktionalität die wir benötigen um diesen hübschen Date-Picker einzublenden.
Die modernizr Bibliothek dagegen hilft uns herauszufinden ob der Browser, den der Benutzer momentan verwendet die gewünschten HTML5 Features unterstützt.
Nun müssen wir also bei unseren Formularen prüfen, ob der Browser die nötigen Funktionen kennt und bei Bedarf die jQuery Klassen einbinden. Das Ganze ist dank der Einfachheit von Modernizr und jQuery ziemlich simpel.
Wechseln wir zu unserer View und fügen die Referenzen auf die nötigen Skripte und CSS Dateien ein:
<script src="@Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.js")" type="text/javascript"></script>
<link href="@Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
Unten in der View fügen wir nun eine Modernizr Abfrage ein und prüfen, ob der Browser das DateTime-Feld unterstützt, und wenn nicht lassen wir jQuery das Ganze für uns regeln:
<script type="text/javascript">
$(function () {
if (!Modernizr.inputtypes.date) {
$("input[type='datetime']").datepicker();
}
});
</script>
Mit dem Befehl $("input[type='datetime']").datepicker(); werden alle Input-Felder vom Typ DateTime durch den jQuery Picker ersetzt. Coole Sache!

Unser Browser kennt den Typ nicht
Kleiner Hinweis am Rande: Das ist nicht wirklich best practice da die Skripte auch geladen werden wenn sie gar nicht benötigt werden (der Browser kennt das HTML5 Feld) ich habe das hier der Einfachheit geopfert.
Und das wars auch schon! Alle Browser die das Feld unterstützen blenden nun ihren Picker ein, ansonsten wird der jQuery Fallback genutzt.
Wir müssen uns auch nicht mit irgendwelchen UserAgent-Prüfungen herumschlagen und lassen das alles Modernizr erledigen, der das intern über JavaScript prüft und somit immer aktuell ist. Das heißt dass wenn irgendwann der IE plötzlich die neuen Typen kennt werden diese auch funktionieren!
Genauso könnt ihr auch bei all den anderen neuen HTML5 Typen vorgehen und euren Usern ein bestmögliches Bedienerlebnis bereiten


Die Windows Azure Produktgruppe hat bekanntgegeben, dass ab sofort der SQL Azure Import/Export Service allgemein produktiv verfügbar ist. Mit diesem Dienst ist es sehr leicht möglich, bestehende lokal betriebene Datenbanken leicht in die Cloud auf SQL Azure zu bringen und existierende SQL Azure und SQL Server Datenbanken problemlos im Windows Azure Blob Storage zu archivieren.
Mit der Produktivsetzung des SQL Azure Import/Export Service werden auch einige Verbesserungen am Dienst verfügbar:
Der Dienst steht kostenlos zur Verfügung. Es fallen lediglich die üblichen Kosten für Datentransfer und Blob Storage (für die Ablage der archivierten Datenbanken) an.
Weitere Informationen