code it

Martins Tech Blog

SQL Server 2012 und die Format-Funktion

Eigentlich ist Formatierung von Daten in meinen Augen nicht wirklich eine Aktion, die zwingend von der Datenbank durchgeführt werden muss. Aber wie es häufig ist, so gibt es auch hier Anwendungsszenarien in denen dies ein durchaus sinnvoller Weg ist.

In den bisherigen Versionen von SQL Server gestaltete sich dies aber immer etwas schwierig, denkt man nur an verschiedene Datumsformatierungen. Die Funktion CONVERT bot zwar schon begrenzt die Möglichkeit, hier Einfluss zu nehmen, aber wenn man bedenkt, dass für Datumsformate die Auswahlmöglichkeit auf "mit Jahrhundert oder ohne" begrenzt war, so schaute man schon etwas neidisch auf die Möglichkeiten, die beispielsweise die .NET CLR mit string.Format bot.

Mehr...

WIX und das "Unhandled Extension Element"

Zur Erstellung eines Installers für eine Webanwendung verwende ich WIX (Windows Installer XML). Teil dieses Installers ist es auch, das Virtual Directory im IIS anzulegen. Dafür gibt es die WIX IIS Extensions. Um diese verwenden zu können, muss man einfach einen neuen XML-Namespace hinzufügen - so die Information in verschiedenen Blogbeiträgen zum Thema. Gesagt - getan:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
</Wix>

Und schon funktioniert Intellisense im Visual Studio und man kann die Erweiterungen iis:WebVirtualDir oder iis:WebApplication verwenden. Was diese Blogeinträge nicht verraten: Versucht man nun einen Build des Projekts, so wirft Visual Studio die Fehlermeldung

The Component element contains an unhandled extension element 'iis:WebVirtualDir'.  Please ensure that the extension for elements in the 'http://schemas.microsoft.com/wix/IIsExtension' namespace has been provided.

Problem ist nun nämlich noch, dass zwar der Namespace deklariert ist, aber die Implementierung der Erweiterung nicht gefunden werden kann, weil die dazu passende Assembly nicht referenziert ist. 

Die Lösung des Problems ist dann auch denkbar einfach: Zusätzlich zur Deklaration des Namespaces IIsExtension muss auch die Assembly WixIIsExtension.dll referenziert werden.

ReadOnly(true) vs. Editable(false)

Der DefaultModelBinder in ASP.NET MVC ist die Klasse, die anhand von jeder Menge Magie die im Post enthaltenen Daten in die jeweiligen Properties im Model schreibt. Wenn alle Eigenschaften öffentliche Getter und Setter haben und auch auf der Seite bearbeitbar sein sollen, dann funktioniert diese Magie auch problemlos.

Spannend wird es beispielsweise dann, wenn man Eigenschaften des Models auf der Seite zwar anzeigen, dem Benutzer aber nicht erlauben möchte diese Werte zu ändern. Nichts leichter als das, gibt es doch das ReadOnlyAttribute. Aber schon dann wenn das erste Mal ein Post vom Client zurück an den Server geschickt wird, merkt man, dass ReadOnly keine so gute Idee ist, denn der DefaultModelBinder nimmt dieses Attribut sehr ernst und mit dem ReadOnly-Attribut markierte Eigenschaften werden genauso behandelt, wie auch Eigenschaften ohne öffentlichen Setter behandelt werden würden - sie werden ignoriert.

Ursache ist die interne Methode ShouldUpdateProperty. Diese ermittelt (wie der Name schon sagt), ob es sich um eine Eigenschaft handelt, die beim Binden beachtet wird oder nicht.

Mehr...

Databinding mit der Windows Phone Application Bar

Für Silverlight-Anwendungen hat sich das MVVM-Pattern sehr gut bewährt, bietet es doch einige Vorteile. Und viele Entwickler machen sogar einen Sport daraus, die Trennung zwischen View und ViewModel so konsequent durchzuziehen, dass überhaupt kein Code mehr in der Codebehind-Datei steht, denn Commands im ViewModel sind wesentlich besser testbar als Code in irgendwelchen Codebehinds. Entwickelt man für Windows Phone, so stößt man spätestens dann an seine Grenzen, wenn man die Application Bar verwenden möchte und die Buttons oder Menüeinträge an Commands aus dem ViewModel binden möchte. Den Grund dafür findet man auch relativ schnell in der MSDN.

Because the Application Bar is not a Silverlight control, it does not support some of the common control features, such as data-binding.

Damit ist man zunächst einmal darauf beschränkt, die Events wieder in der Codebehind-Datei abzufangen und dann gleich dort zu verarbeiten oder an das ViewModel weiterzugeben. So richtig schön sind beide Möglichkeiten nicht.

Mehr...

AdControl ohne Werbung

Das Microsoft Advertising SDK bietet auf einfach Art und Weise die Möglichkeit, in die Apps, die man kostenfrei im Marketplace anbietet oder in Apps im Trial-Mode Werbung einzublenden. Im einfachsten Fall befolgt man die Anleitung, und hat mit wenigen Schritten Erfolg. Was tut man aber, wenn man trotz der Anleitung keine Werbung sieht?

Ist das AdControl auf der Seite auch eingebunden?

Um das AdControl einzubinden ist eine Referenz auf Microsoft.Advertising.Mobile.UI notwendig. Die entsprechende Assembly liegt dem SDK bei. Beim Einbinden muss man darauf achten, die Eigenschaften Width und Height auf die Werte zu setzen, die man bei der Einrichtung des Werbeblocks angegeben hat.

<UI:AdControl Height="80" Width="480" ApplicationId="test_client" AdUnitId="Image480_80"/>

Abgesehen davon sollte man auch ApplicationId und AdUnitId setzen, aber das bemängelt das Control ja direkt als Exception. Zu Testzwecken kann man die Applikations-Id "test_client" und die Werbeblock-Id "Image480_80" (alternativ: "TextAd" oder "Image300_50") verwenden. Nun sollte ein Testbild angezeigt werden. Für das Release sollte man hier dann auf jeden Fall seine registrierten Ids eintragen.

Stimmen die Voraussetzungen?

Wird immer noch nichts angezeigt, sollte man noch einen Blick in die WMAppManifest werfen. Damit das Control funktioniert, sind mindestens folgende Einträge notwendig:

<Capabilities>
  <Capability Name="ID_CAP_NETWORKING" />
  <Capability Name="ID_CAP_MEDIALIB" />
  <Capability Name="ID_CAP_PHONEDIALER" />
  <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
  <Capability Name="ID_CAP_IDENTITY_USER"/>
</Capabilities>

Wozu das AdControl die Telefonie-Voraussetzung braucht ist mir zwar nicht klar, aber es ist so. Bei mir war das Problem im übrigen der fehlende Eintrag für User-Identity.

Exam 71-599: Designing and Developing Windows Phone Applications

Es ist nun schon ein paar Monate her. Im April hab ich bei den Beta-Prüfungen für Windows Phone Development mitgemacht. Das Ergebnis hat ein paar Wochen auf sich warten lassen, aber letztenendes war das Ergebnis dann doch ein "Passed".

Interessant wurde es danach: Für den MCPD in Windows Phone Development benötigt man zusätzlich als Voraussetzung noch den MCTS "Silverlight 4 Development" (70-506) als auch den MCTS "Accessing Data with .NET Framework 4" (70-516). Erstere hatte ich ja bereits, zweitere kam mit der Upgrade-Prüfung von Webdeveloper 3.5 auf 4 mit - dachte ich zumindest, denn bei der Upgrade-Prüfung wurde mit automatisch ein MCTS für "Data Access in .NET Framework 4" gutgeschrieben.

Wie sich dann herausstellte musste ich Microsoft erst an der Hotline fragen, ob "Accessing Data" das gleiche ist wie "Data Access". Die interne Klärung hat aufgrund der Urlaubszeit dann auch ein paar Wochen gedauert. Letztenendes ist der Status aktuell wohl so, dass beides identisch ist, aber dieser Pfad bisher nicht vorgesehen war. Auf dem Papier und in den Mails die ich von Microsoft erhalten habe, habe ich nun wohl schon den MCPD-Status in Windows Phone Development, aber im offiziellen Transcript wird dies erst ab Jahresende zu sehen sein.

[edit 12.12.2011] Seit heute ist der MCPD Status "Windows Phone Developer" auch ganz offiziell im Transcript. Microsoft hat sein Versprechen also gehalten. Damit dürfte dann wohl auch der Weg für alle anderen geebnet sein, die den gleichen Pfad wie ich nehmen.

Treffen der .NET Usergroup Dresden

Das Oktober-Treffen der .NET Usergroup Dresden wird am 27.10.2011 in den Räumen der T-Systems MMS stattfinden. Das Treffen beginnt wie gewohnt um 18:00 Uhr. Detaillierte Informationen zum Termin selbst und eine Möglichkeit zur Anmeldung finden sich auf der Seite der Usergroup.

Thematisch wird es an diesem Abend um die Neuigkeiten gehen, die Microsoft im letzten Monat auf der Build-Konferenz in Anaheim vorgestellt hat - und im speziellen um Windows 8 und die Anwendungsentwicklung für das neue Betriebssystem. Peggy und Lars werden uns durch den Abend führen und sowohl auf die Grundlagen eingehen als auch anhand von ein paar Beispielen zeigen, wie man vorgehen kann.

Im Anschluss daran wird es wieder die Möglichkeit zum gemeinsamen netzwerken geben.

Es gibt aber noch einen weiteren Grund zur Freude: Die Xing-Gruppe der .NET Usergroup Dresden hat seit heute offiziell 111 Mitglieder. Um das zu feiern sponsort Unique Software der Usergroup drei Bücher zu den Themenbereichen Webentwicklung, HTML 5 und WPF, die an diesem Abend unter den anwesenden Teilnehmern verlost werden.

Einprägsames Office365 OWA

Wer von unterwegs auf seinen Exchange zugreifen möchte und keine Lust hat, lange Mails auf dem Smartphone zu schreiben, der verwendet sicher den Outlook Web Access. Bei SaaS-Produkten wie Office365 hat man nun selbst recht wenig Einfluss auf die Konfiguration des Servers und so wird auch hier der Servername bei der Einrichtung von Microsoft festgelegt. Möchte man sich nun mit dem eigenen OWA verbinden, muss man sich diesen Servernamen merken, auch wenn man inzwischen nicht mehr die Standard-Domain verwendet, sondern die eigene Domain hinterlegt hat.

Muss man nicht, wie ich heute gelernt habe.

Zum einen vergibt Microsoft selbst einen Alias. Unter der Url http://outlook.com/contoso.com - wobei contoso.com durch die eigene Domain ersetzbar ist ;) - kann man Zugriff auf seine persönliche Instanz erhalten. Diese Url ist schon wesentlich einprägsamer als der interne Servername.

Zum anderen hat man, so man die Einrichtung für den Zugriff aus Outlook vorgenommen hat, einen CNAME-Eintrag für seine Domain vorgenommen (http://autodiscover.contoso.com). Unter dieser Url ist nicht nur das Desktop-Outlook in der Lage, die Konfiguration automatisch vorzunehmen, sondern sie erlaubt auch Zugriff auf den eigenen OWA.

Beide Möglichkeiten habe ich in der Dokumentation von Office365 nicht gefunden (zumindest den ersten hätte ich dort erwartet), aber vielleicht hab ich auch nur an der falschen Stelle gesucht.

Intellisense für eigene JavaScript-Funktionen

Seit Visual Studio 2008 gibt es die Möglichkeit, JavaScript-Funktionen so zu dokumentieren, dass auch die Intellisense in der Lage ist, Informationen anzuzeigen. Um so erstaunter bin ich jedes Mal, noch häufig auf Konstrukte wie diese hier zu stoßen:

// function that implements some magic
function DoSomething(parameter) {

}

Der Versuch ist ganz gut, aber es geht noch besser. Nachteil dieser Art der Dokumentation ist nämlich, dass Intellisense dann genau auch nur die Methodensignatur anzeigt, nicht aber nähere Informationen zur Methode.

Mit nur einer kleinen Umstellung kann man diese Unterstützung aktivieren:

function DoSomething(parameter) {
    /// <summary>
    /// function that implements some magic
    /// </summary>
    /// <param name="parameter">the dom element's id</param>

}

Was auffällt: Der Aufbau der Dokumentation ist dem was wir schon für C#-Funktionen kennen sehr ähnlich. Einziger Unterschied: In C# wird der Kommentar über die Methode geschrieben und hier in die Methode. Ab diesem Zeitpunkt ist Visual Studio in der Lage, die Informationen wie gewohnt auch schon während des Tippens anzuzeigen.

Wie schon beschrieben ähnelt der Aufbau sehr dem, was man schon von der Dokumentation in C# kennt - es sollte also keine zu große Einstiegshürden für Entwickler geben. Wer eine kurze Einführung braucht, dem sei der Blogpost von Bertrand Le Roy ans Herz gelegt.

HtmlHelper und Interfaces

MVC-Views an ein Modell zu binden ist eigentlich ganz einfach: Man definiert eine Klasse, und typisiert die View mit Hilfe von @model. Das Ganze funktioniert super mit konkreten Typen und auch mit Interfaces:

@using EmployeeApplication.Models
@model Employee

Name:  @Html.DisplayFor(m => m.LastName), @Html.DisplayFor(m => m.FirstName)
Salary: @Html.DisplayFor(m => m.Salary)

Mein Beispiel ist recht einfach umrissen: Es gibt eine Klasse Employee, die einen Mitarbeiter eines Unternehmens definiert, mit typischen Eigenschaften wie Name und Jahresgehalt. Mit Hilfe der Html-Helper-Methode DisplayFor werden die Daten des jeweiligen Mitarbeiters angezeigt.

So weit alles recht unproblematisch.

Nicht immer möchte man auf konkrete Typen binden. Aus diesem Grund ändere ich mein Modell etwas um: Es wird das neue Interface IPerson definiert. Dieses definiert die Eigenschaften einer Person - also Vorname und Nachname. Davon abgeleitet wird nun noch das Interface IEmployee definiert, das IPerson um die Eigenschaft Jahresgehalt erweitert.

Mehr...