code it

Martins Tech Blog

Rückblick auf das mobilecamp Dresden

Es ist zwar noch nicht vorbei, aber ich werde den Rest des Tages und auch morgen leider nicht mehr am mobilecamp Dresdenteilnehmen können. Trotzdem möchte ich über den heutigen Tag ein paar Worte verlieren.

Heute und morgen findet hier in Dresden in der Informatikfakultät das mobilecamp Dresden statt. Der Name ist Programm, handelt es sich hierbei doch um ein Barcamp mit der thematischen Ausrichtung auf die Entwicklung mobiler Anwendungen. Ich war nun schon auf verschiedenen Open Spaces, von daher ist mir das Konzept der Unkonferenz nicht ungeläufig; jedoch ist mir nach wie vor der Unterschied zwischen Barcamp und Open Space nicht klar, sind sie in der Praxis in meiner Erfahrung doch gleich. Aber das soll nicht Thema dieses Posts sein.

Inhaltlich geht es um mobile Entwicklung und damit ist auch schon gesetzt, wer sich hier hauptsächlich einfindet. Und im Grunde kann man anhand der Teilnehmer auch gut die Marktmacht der jeweiligen Marktteilnehmer beobachten. Hauptsächlich handelt es sich hierbei um Entwickler von Apps für iPhone und iPad, an zweiter Stelle kommt die Android-Fraktion und unter ferner liefen dann solche Leute wie ich, die auch den Microsoft Markt bedienen können.

So wundert es auch nicht, dass es inhaltlich mehrheitlich um Themen ging, die sich rund um iPhone oder Android-Entwicklung drehen. Aber auch für mich hat sich heute das ein oder andere Thema gefunden, bei dem ich gern mitdiskutiert habe: So habe ich mich bei folgenden Sessions eingebracht:

  • Chancen und Risiken von Kooperationsmarketing
  • Ausblicke auf die Zukunft mobiler Endgeräte
  • Möglichkeiten von CSS3 zur Optimierung von Webseiten auf mobile Endgeräte

Leider musste ich nach dem Mittagessen das Barcamp verlassen. Trotzdem waren die drei Sessions am Morgen eine Bereicherung und ich kann es jedem nur empfehlen, der mit der Entwicklung auf oder für mobile Endgeräte zu tun hat und diskutieren oder lernen möchte oder auch nur seinen Horizont etwas erweitern möchte.

Rückblick auf die Dotnet Cologne 2011

Inzwischen ist es gut eine Woche her, seit ich und viele andere aus der .NET-Community nach Köln gepilgert sind, um an der diesjährigen Dotnet Cologne teilzunehmen. Ich hatte im letzten Jahr das erste Mal das Vergnügen und fand diese Veranstaltung so gut, dass ich auch dieses Jahr unbedingt mit dabei sein wollte. Was mich besonders an dieser Konferenz begeistert ist einerseits, dass sie nicht so sehr kommerzialisiert ist, wie es andere Konferenzen sind und trotzdem den anderen Konferenzen inhaltlich in nichts nachstehen. Das liegt daran, dass der Grundgedanke dazu aus der .NET Community geboren wurde - namentlich von den .NET Usergroups Köln und Bonn. Ich hoffe, dass das auch noch eine Weile so bleiben wird.

Nun aber zum eigentlichen Tag: Der diesjährige Veranstaltungsort im Media Park war leicht mit der S-Bahn zu erreichen und nach einer Registrierung konnte das Netzwerken bei einem kleinen Frühstück auch schon beginnen. Ich habe mich sehr gefreut, das ein oder andere bekannte Gesicht wiederzusehen und auch Leute mal persönlich kennenzuloernen, die ich bisher nur virtuell kannte. Ein Blick auf die Agenda zeigte, dass für den Tag nur 5 Sessions geplant waren mit großen Pausen von 30 Minuten und aufwärts. Was für mich auf den ersten Blick etwas schade war, weil da in Summe locker noch eine weitere Session Platz gehabt hätte, zeigte sich doch als sehr sinnvoll, denn so blieb gut Zeit für Sessions, die etwas überzogen bzw. auch für Gespräche untereinander.

Wie sah nun mein persönlicher Sessionplan aus? Den Beginn machte Ilker, der in 60 Minuten in Agile Architekturen eintauchte. Er zeigte anhand von zwei Architekturkonzepten, die für sich selbst in Anspruch nehmen, agil zu sein, ob diese die Kriterien von Agilität unterstützen. Ich denke, über das Thema hätte man gut und gerne noch eine Stunde länger philosophieren können, auch weil ein 10-Minuten-Überflug über eine Architektur nicht erlaubt, diese in Gänze zu erfassen und einzuschätzen. In diesem Zusammenhang fand ich auch schade, dass es dieses Mal keine Abendveranstaltung gab, ich hätte mich hier gern mit ihm noch länger drüber unterhalten.

Nach einer kurzen Pause ging es für mich dann weiter mit Daniel, der eine Session zum Thema REST gab. Ich habe mir erhofft, etwas genaueres über die Microsoft Web API zu erfahren - und meine Hoffnung wurde letzenendes auch erfüllt. Mit einer sehr unterhaltsamen Präsentation (so habe ich etwas über Forrest Gump und auch über Dory aus Finding Nemo gelernt), gab Daniel einen Überblick über den State of the art. Ich persönlich hätte diese Session nicht ganz auf Level 400 eingeordnet, aber dieses Empfinden kann sowohl an meinen bisherigen Erfahrungen als auch an der Art von Daniels Didaktik liegen - vielleicht eine Kombination aus beidem.

Nach einem gefährlichen Mittagessen, und der Lunch-Session ging es für mich dann zur LINQ-Session mit Bart de Smet. Thematisch ging es hier zunächst darum, LINQ beizubringen, schon zur Designzeit nur die möglichen Operatoren anzuzeigen. Dann ging es weiter mit Serialisierung von Expression Trees, einem Ausflug in die Reactive Extensions und einen Solver für Sudokus auf LINQ-Basis. Auch wenn es inhaltlich an der LINQ-Front nicht allzu viel Neues gibt, so hat es mich sehr gefreut, ihn mal live zu sehen und wer ihn coden sieht, der möchte gern im Anschluss alles mit LINQ machen.

Zum Schluss habe ich mir dann noch die Einführung in MEF von Rainer angeschaut. Auch wenn MEF letztenendes in der Anwendung recht simpel ist und ich mich im vorab gefragt habe, wie man da eine Stunde drüber reden kann, so hat er den Inhalt doch sehr unterhaltsam, enthusiastisch und mit vielen Beispielen rübergebracht. Falls jemand die Samples sucht, auf die er bei seiner Session verwiesen hat: diese sind in seinem englischsprachigen Blog verfügbar.

Zusammengefasst: Ich bin nach wie vor von dem Konzept der Community-Konferenzen überzeugt und ich hoffe, dass auch im kommenden Jahr die Dotnet Cologne eine Fortsetzung findet. Macht weiter so, ich wär gern wieder mit dabei.

Lesbare Bytes

Das Problem ist einfach umrissen: Man hat die Größe einer Datei oder (auch gern genommen) eine Größenbeschränkung in Bytes vorliegen und möchte diese dem Benutzer anzeigen. Aber nur die wenigsten Benutzer können mit der Größenangabe 1.048.576 Bytes etwas anfangen. Also möchte man die Größe dem Benutzer in ihm bekannten Größenangaben anzeigen - so wie man es von Windows kennt. Das .NET Framework selbst kennt meines Wissens eine solche Funktion nicht und daher ist es jedem Entwickler selbst überlassen, wie er diese Umrechnung vornimmt.

Auf meiner Suche nach einer Lösung für genau dieses Problem bin ich über einige Lösungsvorschläge bei stackoverflow gestolpert und einen davon fand ich extrem gut, so dass ich dem Problem und möglichen Lösungen diesen Blogpost widmen möchte.

1. Lösung: While-Loop

Dieser Ansatz wird gern genommen und liegt ja in der prozeduralen Denke auch auf der Hand: Man dividiert so lange durch 1024, bis eine Zahl übrig bleibt, die kleiner als 1024 ist. Hat man sich nun noch gemerkt, wie häufig man dies angewandt hat, so weiß man auch was man als Einheit dahinter schreiben muss.

var unit = new[] { "B", "KB", "MB", "GB", "TB", "PB" };
var index = 0;
var value = bytes;

while (value >= 1024)
{
 index++;
 value /= 1024;
}

var readable = string.Format("{0} {1}", value, unit[index]);

 

2. Lösung: Windows bemühen

Wie ich schon einleitend beschrieben habe, kann Windows diese Berechnung ja. Warum also nicht mit unmanaged Code auf die passende Windows-Funktion zugreifen? Die Shlwapi.dll stellt eine entsprechende Funktion bereit, mit der diese Formatierung vorgenommen werden kann.

[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
public static extern long StrFormatByteSize(
 long fileSize,
 [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer,
 int bufferSize);


var sb = new StringBuilder(11);
StrFormatByteSize(bytes, sb, sb.Capacity);
var readable = sb.ToString();

OK, es ist eine Möglichkeit, aber keine die ich präferieren würde.

 

3. Lösung: Mathematisch

Und nun zu der Lösung, auf die ich zugegebenermaßen nicht gekommen bin, die ich aber sehr charmant finde. Mit Hilfe nur weniger mathematischer Funktionen lässt sich die Schleife aus der Lösung 1 ersetzen. Durch eine geschickte Kombination von Logarithmus-, Potenz- und Rundungsfunktionen lässt sich sowohl der gerundete Wert als auch die anzuzeigende Einheit ermitteln.

var unit = new[] { "B", "KB", "MB", "GB", "TB", "PB" };
var index = Convert.ToInt32(
    Math.Floor(Math.Log(Math.Abs(bytes), 1024)));
var value = Math.Round(bytes / Math.Pow(1024, index), 2);
var readable = string.Format("{0} {1}", value,  unit[index]);

Einziger Wert für den diese Variante nicht funktioniert ist 0 Byte.

Wie ganz häufig, so gibt es auch hier viele Wege, die zum Ziel führen und es bleibt jedem selbst überlassen, welchen Weg er wählt.

AllowHtml in ASP.NET MVC3

Meist ist es ja bei Eingabeformularen im Web gewünscht, dass eingegebene Werte beim späteren Rendern keinen Schaden anrichten. Genau dafür gibt es Request Validation. Dieses Feature sorgt dafür, dass keine Script-Tags eingegeben werden können, die später dann für Cross-Site-Scripting verwendet werden.
 
Nun gibt es aber doch auch Momente, in denen man doch möchte, dass HTML-Code in ein Textfeld eingegeben werden kann - z.B. dann wenn vom Benutzer Content für Webseiten generiert werden soll. Ein solches Anwendungsszenario ist häufig damit verbunden, dass ein Richtext-Editor zum Einsatz kommt, der dann eine normale Textarea mit entsprechenden Funktionen versieht. Typische Vertreter dafür sind TinyMCE oder auch der CKEditor. Wenn man die hier eingegebenen Daten dann versucht, an die Action zu übergeben, so wird das Ganze von der Request Validation bemerkt und eine entsprechende Fehlermeldung ausgegeben.
 

 
In der Fehlermeldung gibt es auch gleich einen Hinweis, was man ändern muss, damit man den Post trotzdem durchführen kann: Die Request-Validation für sämtliche Posts in der web.config zu deaktivieren. Diese Lösung ist nicht ganz so schlau.
 
Lösung 2, und bis MVC 2 auch die einzig andere Möglichkeit, ist es, die Request Validation für die komplette Action zu deaktivieren. Dazu setzt man einfach das ValidateInput-Attribut auf false.
 
[HttpPost, ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Create(Article article)
{
// do some database logic here
return View();
}
 
Ok, diese Lösung ist schon besser, da man eine bessere Kontrolle darüber hat, für welche Aktionen es gelten soll. Aber auch das ist noch nicht ganz optimal. Hier kommt nun das AllowHtml-Attribut von ASP.NET MVC 3 zur Geltung. Damit kann man auf einzelnen Properties des Models definieren, dass für diese die Request Validation nicht durchgeführt wird, da hier HTML-Code beinhaltet sein kann.
 
public class Article
{
 public int Id { get; set; }

 [AllowHtml]
 public string Content { get; set; }
}
 
Man muss nun nicht mehr sämtliche Properties von der Request Validation ausschließen, sondern kann hier dediziert definieren, wo HTML-Code enthalten sein darf und wo nicht.

Einladung zum Treffen der .NET Usergroup Dresden am 27.04.2011

Das kommende Treffen der .NET Usergroup Dresden findet am 27.04. um 18:00 Uhr statt. Wir treffen uns dieses Mal wieder in den Räumen der Communardo Software GmbH.
 
Thematisch widmen wir uns dieses Mal wieder den Web-Technologien etwas mehr. Diskussionsgrundlage und Beispiel soll die Anwendung BizzBingo sein. Diese verwendet unter anderem die folgenden Technologien und Frameworks:
  • ASP.NET MVC 3 mit Razor View Engine
  • Team City
  • Windows Azure
  • CQRS Architektur
  • BDD Unit Tests
  • Azure Deployment via PowerShell
  • jQuery
  • MSBuild
  • NuGet
Robert wird das Projekt vorstellen, das ursprünglich beim WebCamp im Juni 2010 in München seinen Anfang fand. Er wird auf die Technologie eingehen und auch den ein oder anderen Stolperstein. Ich denke bei dieser Themenvielfalt wird es sicher auch im Anschluss noch Bedarf und Gelegenheit für eine offene Diskussion geben.

Nachlese zum Treffen der .NET Usergroup Dresden vom 17.03.2011

Gestern gab es gleich zwei Premieren bei der .NET Usergroup Dresden.

Premiere 1: Wir haben das erste Mal ein Coding Dojo durchgeführt. 18:00 Uhr ging es los. Nachdem beim letzten Usergroup-Treffen die ein oder anderen Fragen auch in Richtung testgetriebene Entwicklung und die Sinnhaftigkeit gingen bin ich in ein paar einleitenden Worten darauf eingegangen, was testdriven eigentlich bedeutet und wie man dabei vorgeht.

Ausgehend davon wurde der Rahmen für den Abend gesteckt. Ich erklärte die Grundbegriffe von Coding Dojos und weil es für viele das erste Dojo war, begannen wir mit der recht einfachen Kata FizzBuzz. Im Vordergrund für diesen Abend stand einfach nur, allen ein Gefühl für TDD zu geben und die Angst vor dem Unbekannten "Coding Dojo" zu nehmen. Zweite Kata des Abends sollte nach einer Abstimmung Kata Potter sein, die aber nach unterschiedlichen Lösungsvorschlägen und Herangehensweisen irgendwann dann abgebrochen wurde.

Für mich war es das erste mal als Sensei und ich habe ein paar wertvolle Schlüsse ziehen können. Zunächst habe ich mich sehr gefreut, dass sich auch Usergroup-Teilnehmer, die eigentlich als Muttersprache VB.NET sprechen (wie sie es selbst genannt haben) in einem C#-Projekt mitgearbeitet haben, auch wenn "dieses komische Semikolon immer" gestört hat. Mir hat es sehr gut gefallen, dass eben nicht nur ein Vorturner da war, sondern dass wir die Gelegenheit hatten, vom Wissen aller zu profitieren, die sich freiwillig gemeldet haben, an der Kata mitzumachen. Und hier hat sich wieder gezeigt, dass es wichtig ist, nicht vorn still vor sich hin zu programmieren, sondern alle an den Gedanken teilhaben zu lassen.

Es gab aber auch ein paar Lehren für mich: Bei einer Gruppengröße von 20 Teilnehmern ist es recht kompliziert alle bei der Sache zu halten. Und, es hat sich herausgestellt, dass es wichtig ist, auch im Dojo die Schritte Red-Green-Refactor alle durchzuführen und es nicht auf Red-Green-Vielleicht-Refactor zu beschränken. Dem resultierenden Code merkt man nämlich an, dass er dringend ein Refactoring benötigt. Und zu guter Letzt ist es wichtig, nicht blind drauf los zu programmieren, sondern sich auch zu Beginn schon mal Gedanken darüber zu machen, in welche Richtung es gehen soll. Denn was nutzen 7 grüne Tests, wenn man der Lösung noch nicht wirklich näher gekommen ist und erst dann überlegt, wie man das Problem denn lösen könnte.

Zusammenfassend: Es war ein gelungener erster Dojo-Abend. Ich denke, wir werden das auch weiter fortführen und gelegentlich Dojo-Abende einstreuen und die Schlüsse die ich und auch die anderen aus diesem Abend ziehen konnten werden dann sicher auch Eingang finden. Die Resonanz war zumindest eindeutig positiv. Und nicht zuletzt habe ich mich auch sehr darüber gefreut, neben den vielen bekannten Gesichtern wieder mal ein paar neue Teilnehmer begrüßen zu dürfen. Ach ja - Premiere 2: Das Treffen fand das erste Mal bei Saxonia Systems statt und es war ein guter Einstand. Offenbar können Softwareentwickler aber mit Gemüse nicht allzu viel anfangen, denn obwohl die freundlicherweise gesponserten belegten Brötchen im wahrsten Sinne weggingen wie warme Semmeln, war die Gemüseplatte fast unberührt.

Mein Blog auf SQLServerBlogs.de

Ende letzten Jahres hatte Constantin die Idee, dass auch für die deutschsprachige SQL Server Community eine Plattform ähnlich den DotNetGermanBloggers gut und sinnvoll wäre. Und diese Idee unterstütze ich.

Dank der Verwendung von von O/R-Mappern verschwindet der direkte Datenbankzugriff inzwischen mehr und mehr in der klassischen .NET-Entwicklung. Trotzdem gibt es auch immer wieder Fälle, in denen das Was-passiert-da-eigentlich oder das Warum-geht-das-jetzt-nicht Probleme bereitet. Und genau dann ist es gut, wenn man auch im deutschsprachigen Raum Hilfe findet.

Deshalb: Ab sofort finden sich meine Blogposts zum Thema SQL Server auch auf SQLServerBlogs.de.

Verwaiste Logins in SQL-Server-Datenbanken neu zuordnen

In meinen Blogpost Verwaiste SQL-Logins auf einem SQL-Server ermitteln hab ich gezeigt, wie man mit Hilfe eines Skriptes ermitteln kann, welchen Logins gar keine Datenbanken mehr zugewiesen sind.

Aber das Thema der verwaisten Logins gibt es auch in umgekehrter Richtung: Jeder der bereits versucht hat, eine Datenbank von einem anderen Server wiederherzustellen und diese Datenbank verfügte über SQL-Benutzer, wird das Problem kennen: In der Datenbank gibt es unter dem Punkt Datenbank -> Security -> Users bereits mehrere Benutzer und diese sind unter Umständen auch mit Berechtigungen versehen, man möchte diese also nicht löschen. Die Benutzer existieren jedoch nicht als Logins unter Security -> Logins. Legt man dann gleichnamige Logins im SQL-Server an, so ist das auch noch recht unproblematisch - zumindest so lange bis man versucht, den neu angelegten Login auf der besagten Datenbank zuzulassen. Diesen Versuch quittiert der SQL-Server mit der Meldung, dass ein Benutzer mit diesem Namen in der Datenbank schon vorhanden ist - womit er ja grundsätzlich auch Recht hat.

 

Allerdings bedeutet das nicht, dass das eben neu angelegte Login aufgrund dieser Tatsache auch automatisch mit Zugriffsrechten auf der wiederhergestellten Datenbank ausgestattet ist.

Die Ursache liegt darin begründet, dass der SQL-Server den Benutzern intern eine SID zuweist. Die SID des Benutzers in der wiederhergestellten Datenbank und die SID des eben erstellten Logins unterscheiden sich.

Abhilfe schafft hier die Systemprozedur sp_change_users_login. Mit dem Parameter 'report' aufgerufen erhält man zunächst eine Auflistung aller Benutzer, die über keine Zuordnung zu Logins verfügen.

 

Nun steht also fest, dass es in der Datenbank fünf ungemappte Benutzer gibt. Mit Hilfe der gleichen Prozedur kann man nun auch gleich das Mapping vornehmen. Dazu übergibt man einfach als ersten Parameter 'update_one' und als zweiten bzw. dritten Parameter Benutzer und Login.

Prüft man nun die verwaisten Logins erneut, wird man feststellen, dass dieser Benutzer hier nicht mehr erscheint und versucht man ein Login auf der Datenbank, wird man merken, dass das nun funktioniert.

Remote Desktop Connection Manager

Wer oft mit vielen Remote-Desktop-Verbindungen arbeitet kennt das Problem: Für jede Verbindung wird eine eigene *.rdp-Datei angelegt und diese Dateien schwirren dann irgendwo auf dem System herum. Nun bin ich letzte Woche dank eines Tipps über ein sehr nützliches Tool gestolpert, das es seit etwa 10 Monaten gibt und das auch schon öfter in diversen Blogs vorgestellt wurde (z.B. auch im Code-Inside Blog) - der Remote Desktop Connection Manager.

Hier lassen sich mehrere Remote Desktop Connections zu Gruppen zusammenfassen. Diesen Gruppen kann man gemeinsame Einstellungen verpassen, so dass beispielsweise alle Verbindungen der gleichen Gruppe mit identischen Credentials geöffnet werden, die man dann nur in den Gruppeneigenschaften pflegen muss. Diese Vererbung beschränkt sich aber nicht nur auf Credentials, sondern auch auf andere Eigenschaften wie Bildschirmauflösung, Audioeinstellungen usw. Natürlich lassen sich die Einstellungen auch pro Verbindung einzeln konfigurieren.

Im Gegensatz zu den *.rdp-Dateien können hier innerhalb der Datenstruktur auch Credentials gespeichert werden, was ebenfalls ein Vorteil ist. Die Import-Schnittstelle aus Textdateien ist inzwischen als deprecated gekennzeichnet, aber *.rdg-Dateien sind relativ selbsterklärende XML-Strukturen. Ist das Kennwort verschlüsselt abgelegt, so lässt es sich auf einem anderen Rechner nicht entschlüsseln, was aber aus meiner Sicht auch nicht weiter schlimm ist. Wenn man dieses Tool wirklich braucht, so ist man vermutlich häufig mit Admin-Rechten auf irgendwelchen Rechnern unterwegs und dann wäre es fatal, wenn man durch einfaches Kopieren der *.rdg-Datei die vollen Berechtigungen hätte, ohne Kenntnis vom Kennwort zu haben. Wie es aussieht, kann man das umgehen, indem man das Kennwort im Klartext speichert und dann sollte es problemlos möglich sein, eine *.rdg-Datei auch an Kollegen zu geben.

Einladung zum Treffen der .NET Usergroup Dresden am 17.03.2011

Am 17.03.2011 wird das nächste Treffen der Usergroup stattfinden. Dieses Mal kommen wir so denke ich allen Teilnehmern von der Altstadt-Seite etwas entgegen, denn das Treffen findet bei Saxonia Systems statt und beginnt um 18:00 Uhr. Wie beim letzten Treffen mit großer Mehrheit beschlossen wurde, wollen wir dieses Mal ein Coding Dojo durchführen.

Damit alle einen groben Einblick haben, wohin die Reise geht, werde ich die Gelegenheit nutzen und zu Beginn anhand eines einfachen Beispiels die grundlegende Herangehensweise an testgetriebene Entwicklung erklären. Das Beispiel wird wohl jedem bekannt sein und daher können wir uns hier auf das Wie und nicht so sehr auf das Was konzentrieren. Im Anschluss daran werden wir zunächst eine einfache Kata gemeinsam durchführen und so das eben gelernte Vertiefen. Ich werde noch ein paar schwierigere Übungen mitbringen, so dass wir dann darunter eine aussuchen können, die wir bearbeiten.

Der Abend soll den Auftakt dazu geben, zukünftig ab und zu das ein oder andere Dojo durchzuführen. Wer sein eigenes Notebook mitbringen möchte, um selbst an der Lösung der Aufgaben zu arbeiten, ist herzlich dazu eingeladen. Das Dojo selbst wird an einem zentralen Notebook durchgeführt, so dass alle Beteiligten an den Gedanken von Driver und Copilote teilhaben können. Ich bin schon sehr gespannt auf diesen Abend.

Damit wir besser planen können, bitte ich alle potenziellen Teilnehmer um Eintragung in die Teilnehmerliste.