Uli Armbruster: WhatsApp auf Android automatisch in die Cloud sichern

Ist dir das auch schon passiert,

  • dass dein Handy geklaut wurde oder kaputt ging und deine ganzen WhatsApp Nachrichten, Bilder und Videos weg waren?
  • dass dein Handyspeicher ständig voll ist, weil die Multimedia-Daten von WhatsApp einfach zu groß sind?
  • dass du auf ein neues Handy gerne deine gesamte WhatsApp Kommunikation übertragen hättest

Wenngleich es sehr viele Lösungen im Netz gibt, sind nur wenige davon für den weniger geübten Anwender geeignet. Die Firma MetaCtrl bietet für Android entsprechende Apps an, womit sich Verzeichnisse auf dem Smartphone automatisiert in den eigenen Cloudspeicher synchronisieren lassen. Nutzt du also Dropbox, OneDrive, Google Drive oder Box ohnehin schon, so ist das eine einfache Lösung. Exemplarisch möchte ich das für Dropbox zeigen:

Die zugehörige App heißt Dropsync (für andere Cloud Dienste findest du die zugehörigen Apps hier). Die App einfach installieren und starten. Dann musst du der App Zugriff auf Dropbox gewähren. Dazu einfach das vorausgewählte Dropbox Konto anklicken und zulassen.

2015-04-18 12.09.38

Als nächstes kannst du dann ein Verzeichnis zur Synchronisation auswählen. Angefangen beim lokalen Verzeichnis, was logischerweise ‘WhatsApp’ heißt. Danach musst du das Verzeichnis in der Dropbox auswählen, wohin die Daten gespeichert werden sollen. Am besten kurz ein neues Verzeichnis anlegen, das du auch WhatsApp nennen kannst. Nun muss nur noch die Synchronisationsmethode ausgewählt würden. Ich würde “nur Uploads” vorschlagen. Was das genau bedeutet, könnt ihr in der App nachlesen.

2015-04-18 12.10.16

Der Vorteil ist, dass damit jederzeit lokal Bilder und Videos gelöscht werden können, diese aber weiterhin in der Cloud bleiben. Außerdem ist im lokalen WhatsApp Verzeichnis auch die benötige Datei, welche für eine Wiederherstellung auf einem anderen Handy benötigt wird.

Das Wiederherstellen ist im Übrigens sehr einfach. Auf dem neuen Handy ebenfalls die App installieren, das WhatsApp Verzeichnis in der Dropbox als Quelle auswählen und lokal ein WhatsApp Verzeichnis erstellen. Als Methode wählst du dann “nur Downloads”. Nachdem das Verzeichnis vollständig synchronisiert wurde, kannst du WhatsApp auf dem Smartphone installieren. Beim ersten Starten wird dein Konto erkannt und eingelesen. Voila, alle Daten wieder da. Jetzt solltest du aber nicht vergessen die Synchronisationsmethode wieder auf “nur Uploads” zu stellen.

 

Am Ende habe ich noch mehrere wichtige Hinweise:

  • Denkt gut darüber nach, ob ihr eure Konversationen und Daten in einem Cloud Speicher sichern wollt. Wer allerdings schon WhatsApp nutzt, nimmt es mit dem Datenschutz ohnehin nicht genau.
  • Die kostenlose Variante von Dropsync ist beschränkt. Es können Dateien von max. 8 MB hochgeladen werden, was bedeutet, dass v.a. größere Videos nicht gesichert werden. Bilder und kleine Videos sind in der Regel davon nicht betroffen. Für 6€ gibt es die Variante ohne Einschränkungen.
  • Stellt in den Einstellungen ein, dass nur bei aktivierter W-LAN Verbindung Daten synchronisiert werden sollen.
  • Generell muss natürlich in der Dropbox genügend freier Speicher zur Verfügung stehen. Kleiner Tipp: OneDrive bietet mehr freien Speicher und ist als Sicherungsplatz für Handydaten völlig ausreichend

2015-04-18 12.09.452015-04-18 12.09.53


Einsortiert unter:German, Misc Tagged: Off-Topic

Code-Inside Blog: Using Basic Authentication in ASP.NET WebAPI

Basic Authentication? Are you kidding?

This was my first thought when I was thinking about a simple approach to protect Web APIs, but then I found this nicely written blogpost: Why I love Basic Auth

The topic is still very controversial, but if it done right and you are using SSL: Why not give it a try. There are other well-known examples, like the GitHub API which can be used with Basic Auth.

Short introduction to Basic Authentication

We can all agree that Basic Authentication is dead simple for HTTP Servers and Clients. The Client just needs to send the given Username and Password Base64 encoded in the “Authorization” HTTP header like this:

Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

The “dXN” is just “username:password” encoded in Base64.

Now the Server just needs to decode the Username and Password and get the actual user lookup started. The Server can also inform Clients that the authentication is need via this HTTP Response Header:

WWW-Authenticate: Basic realm="RealmName"

All typical Clients and Servers can handle this “basic” stuff very well.

Basic Auth with ASP.NET WebAPI

The following code is based on this excellent tutorial Authentication Filters in ASP.NET Web API 2 , but I’m leaving out the ASP.NET Identity stuff.

The sample code from Microsoft contains an abstract base filter, which will check the request for the authentication header and will extract username and password.

public abstract class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter
{
    public string Realm { get; set; }

    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        HttpRequestMessage request = context.Request;
        AuthenticationHeaderValue authorization = request.Headers.Authorization;

        if (authorization == null)
        {
            // No authentication was attempted (for this authentication method).
            // Do not set either Principal (which would indicate success) or ErrorResult (indicating an error).
            return;
        }

        if (authorization.Scheme != "Basic")
        {
            // No authentication was attempted (for this authentication method).
            // Do not set either Principal (which would indicate success) or ErrorResult (indicating an error).
            return;
        }

        if (String.IsNullOrEmpty(authorization.Parameter))
        {
            // Authentication was attempted but failed. Set ErrorResult to indicate an error.
            context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request);
            return;
        }

        Tuple<string, string> userNameAndPasword = ExtractUserNameAndPassword(authorization.Parameter);

        if (userNameAndPasword == null)
        {
            // Authentication was attempted but failed. Set ErrorResult to indicate an error.
            context.ErrorResult = new AuthenticationFailureResult("Invalid credentials", request);
            return;
        }

        string userName = userNameAndPasword.Item1;
        string password = userNameAndPasword.Item2;

        IPrincipal principal = await AuthenticateAsync(userName, password, cancellationToken);

        if (principal == null)
        {
            // Authentication was attempted but failed. Set ErrorResult to indicate an error.
            context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);
        }
        else
        {
            // Authentication was attempted and succeeded. Set Principal to the authenticated user.
            context.Principal = principal;
        }
    }

    protected abstract Task<IPrincipal> AuthenticateAsync(string userName, string password,
        CancellationToken cancellationToken);

    private static Tuple<string, string> ExtractUserNameAndPassword(string authorizationParameter)
    {
        byte[] credentialBytes;

        try
        {
            credentialBytes = Convert.FromBase64String(authorizationParameter);
        }
        catch (FormatException)
        {
            return null;
        }

        // The currently approved HTTP 1.1 specification says characters here are ISO-8859-1.
        // However, the current draft updated specification for HTTP 1.1 indicates this encoding is infrequently
        // used in practice and defines behavior only for ASCII.
        Encoding encoding = Encoding.ASCII;
        // Make a writable copy of the encoding to enable setting a decoder fallback.
        encoding = (Encoding)encoding.Clone();
        // Fail on invalid bytes rather than silently replacing and continuing.
        encoding.DecoderFallback = DecoderFallback.ExceptionFallback;
        string decodedCredentials;

        try
        {
            decodedCredentials = encoding.GetString(credentialBytes);
        }
        catch (DecoderFallbackException)
        {
            return null;
        }

        if (String.IsNullOrEmpty(decodedCredentials))
        {
            return null;
        }

        int colonIndex = decodedCredentials.IndexOf(':');

        if (colonIndex == -1)
        {
            return null;
        }

        string userName = decodedCredentials.Substring(0, colonIndex);
        string password = decodedCredentials.Substring(colonIndex + 1);
        return new Tuple<string, string>(userName, password);
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        Challenge(context);
        return Task.FromResult(0);
    }

    private void Challenge(HttpAuthenticationChallengeContext context)
    {
        string parameter;

        if (String.IsNullOrEmpty(Realm))
        {
            parameter = null;
        }
        else
        {
            // A correct implementation should verify that Realm does not contain a quote character unless properly
            // escaped (precededed by a backslash that is not itself escaped).
            parameter = "realm=\"" + Realm + "\"";
        }

        context.ChallengeWith("Basic", parameter);
    }

    public virtual bool AllowMultiple
    {
        get { return false; }
    }
}

There is a small helper class, which will issue an “UnAuthorized”-Response, with the challenge note:

public static class HttpAuthenticationChallengeContextExtensions
{
    public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme)
    {
        ChallengeWith(context, new AuthenticationHeaderValue(scheme));
    }

    public static void ChallengeWith(this HttpAuthenticationChallengeContext context, string scheme, string parameter)
    {
        ChallengeWith(context, new AuthenticationHeaderValue(scheme, parameter));
    }

    public static void ChallengeWith(this HttpAuthenticationChallengeContext context, AuthenticationHeaderValue challenge)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        context.Result = new AddChallengeOnUnauthorizedResult(challenge, context.Result);
    }
}

The real work is now done in this filter:

public class IdentityBasicAuthenticationAttribute : BasicAuthenticationAttribute
{
    protected override async Task<IPrincipal> AuthenticateAsync(string userName, string password, CancellationToken cancellationToken)
    {
        cancellationToken.ThrowIfCancellationRequested(); 

        if (userName != "testuser" && password != "Pass1word")
        {
            // No user with userName/password exists.
            return null;
        }

        // Create a ClaimsIdentity with all the claims for this user.
        Claim nameClaim = new Claim(ClaimTypes.Name, userName);
        List<Claim> claims = new List<Claim> { nameClaim };

        // important to set the identity this way, otherwise IsAuthenticated will be false
        // see: http://leastprivilege.com/2012/09/24/claimsidentity-isauthenticated-and-authenticationtype-in-net-4-5/
        ClaimsIdentity identity = new ClaimsIdentity(claims, AuthenticationTypes.Basic);

        var principal = new ClaimsPrincipal(identity);
        return principal;
    }

}

The Microsoft Sample uses the ASP.NET Identity Stack - for this demo I just hardcoded my expected username and password. If the request contains these credentials the filter will create a new ClaimsPrincipal.

Usage

Using this filter now is pretty simple:

[IdentityBasicAuthentication]
[Authorize]
public class ValuesController : ApiController
{
    ...
}

The “IdentityBasicAuthentication” filter will try to authenticate the user and after that the default “Authorize” filter will kick in.

Pretty simple, right?

The full source code can be found on GitHub.

Happy coding!

Holger Sirtl: Azure News on Friday (KW17-2015)

Nachdem ich nun mehrfach darauf angesprochen wurde, was denn eigentlich mit meinem Blog los sei, da schon länger keine Einträge mehr erschienen sind, möchte ich diese Nachfragen nun doch zum Anlass nehmen, hier wieder aktiv(er) zu werden. Eine Idee, die ich schon etwas länger verfolge ist, regelmäßige (d.h. wöchentliche) Zusammenfassungen aktueller Neuigkeiten rund um Azure zu posten. Immerhin wird es immer anspruchsvoller, sich auf dem neuesten Stand zu halten. Darüber hinaus wird es natürlich auch wieder Blogs zu technischen Themen geben.

Los geht’s also mit den Neuigkeiten aus der aktuellen Woche (KW17):

Datum Nachricht
17.04. Kostenloses eBook: Microsoft Azure Essentials – Azure ML
Dieses Buch gibt einen Überblick über Azure Machine Learning, den Azure Service für Predictive Analytics.
16.04. Azure Friday Video: Azure PowerShell 101 – Managing Azure WebSites
In diesem Video wird gezeigt, wie mit Hilfe von PowerShell Azure Websites bei Problemen analysiert, Fehler gefunden und behoben werden können.
16.04. Docker Client für Windows verfügbar
Mit dem Docker Client können Docker Hosts und Container aus Windows-basierten Umgebungen heraus angesprochen und verwaltet werden.
16.04. Universal Windows Apps SDK für Azure Mobile Engagement verfügbar
Über Mobile Engagement können Analysedaten zur Nutzung mobiler Anwendungen gesammelt und ausgewertet werden. Auch der Versand von gezielten Push Notifications ist möglich. Mit dem SDK können Universal Apps fit für Mobile Engagement gemacht werden.
16.04. Azure Stream Analytics jetzt allgemein verfügbar
Stream Analytics ist ein Service zur Auswertung von Streaming-Daten von z.B. IoT-Geräten, Sensoren, Infrastruktur oder Anwendungen.
16.04. Azure Premium Storage jetzt allgemein verfügbar
Premium Storage ist nun produktiv nutzbar. Damit steht Anwendern ein Azure Speicher mit deutlich erhöhter Performanz zur Verfügung.
15.04. Azure SQL Database: Backup vs. Import/Export
Dieser Blog-Artikel stellt die beiden Optionen, d.h. das eingebaute Backup und die Möglichkeit zum Datenbank-Import/Export gegenüber.
15.04. Azure Media Player veröffentlicht
Mit Hilfe des Azure Media Players lassen sich basierend auf Standards wie HTML5 (MSE/EME) (mit Flash oder Silverlight als Fallback-Lösung) Medienwiedergaben mit adaptivem Streaming umsetzen.
15.04. Z-Ray für PHP von Zend verfügbar als Azure App Service
Z-Ray gibt Entwicklern Insights in ihre PHP Anwendungen.
14.04. Neuer MVA-Kurs: Windows Azure Pack: Express Installation Walkthrough In diesem neuen MVA-Kurs erfährt werden alle Grundlagen zum erfolgreichen Einsatz von Windows Azure Pack erläutert.
14.04. Neuer MVA-Kurs: All About Microsoft Azure Operational Insights
Dieser neue Kurs auf der Microsoft Virtual Academy gibt einen Überblick über Azure Operational Insights.
14.04. Dynamische Manifests, gerenderte Teil-Videos in Media Services
Media Services bieten die Möglichkeit zur Erstellung von dynamischen Manifests sowie die Erstellung von Ausschnitten aus Live Streamings zur Bereitstellung als On-Demand-Content.
14.04. Neuer MVA-Kurs: Windows Azure Pack: Partner Solutions
In der MVA gibt’s einen neuen Kurs, in dem Partner-Lösungen im Zusammenhang mit dem Windows Azure Pack vorgestellt werden.
14.04. Azure Media Services – jetzt CDSA-zertifiziert
Die Media Services haben hinsichtlich der Sicherheit der Medienverarbeitung die CDSA-Zertifizierung (CDSA = Content Delivery and Security Association) erhalten.
14.04. Einfacher Datenimport nach DocumentDB
Stephen Baron, Program Manager, Azure DocumentDB stellt hier das DocumentDB Data Migration Tool vor, mit dessen Hilfe sich bestehende Datenbestände nach DocumentDB importieren lassen.
14.04. Integration einer lokalen Infrastruktur mit Azure
Jim Dial, Principal Content Developer, Cloud+Enterprise, stellt in diesem Blog-Artikel das interaktive “Datacenter Extension reference architecture diagram” vor, mit dessen Hilfe, Integrationsszenarien geplant und diskutiert werden können.
13.04. Azure Media Indexer Spanisch (v1.2)!
Neben Englisch unterstützt der Media Indexer jetzt auch Spanisch.
13.04. Einführung in Live Encoding mit Azure Media Services
Anil Murching, Senior Program Manager, Azure Media Services, gibt in diesem Blog-Artikel einen Überblick über die Möglichkeiten des Live Encodings mit Azure Media Services.
13.04. Azure Media Services jetzt mit Live Encoding, Azure Media Player etc.
Videos können jetzt via Live Encoding live codiert werden. Dabei besteht die Möglichkeit zur dynamischen Paketierung, dynamischen Verschlüsselung, Einfügen von Ad-Markern etc. Der Azure Media Player erlaubt die Erstellung von Wiedergabe-Apps basierend auf verschiedenen Standards wie HTML5, Media Source Extensions (MSE) and Encrypted Media Extensions (EME).

Weitere Informationen

Marco Scheel: Links for 2015-04-16 [del.icio.us]

Sven Hubert: How to use the VSO Task Board to directly close Tasks and don’t have to think about Remaining Work

The TFS Task Board is a comfortable tool to manage and update tasks. Many of our customers are using the TFS Task Board in their daily meetings to coordinate their work. Despite the comfortable handling, there are still functionalities which need manual activity. To reduce this manual effort, TFS ASAP Online includes several automations.

Today, we introduce a new feature concerning the closing of tasks directly on the VSO Task Board. This feature affects the following Process Templates:

» MSF for Agile Software Development

» MSF for CMMI Process Improvement

1

 

Happy day scenario

In the happy day scenario, we assume that finished Work Items are set to Closed. Additional we assume that a Work Item which is set to Closed does not need any further work. Hence, Remaining Work field should be set to zero.

Using Team Foundation Server, the Remaining work can be set to Zero by modifying the process template. For Visual Studio Online this option does not work. The value of Remaining Work is not altered without manual action.

3

As the screenshot above unveils, Remaining Work still remains on its original value, even though the Work Item is set to Closed.

In the happy day scenario, we would expect the following value:

clip_image006

Solution

We are using an Azure-hosted background service to reduce manual activity, establish the happy day scenario and automatically set Remaining Work to zero when the Work Item set to Closed. This feature is now available in TFS ASAP Online, our official extension for Visual Studio Online.

Note that in the described happy day scenario, Completed Work can automatically be increased by another feature of TFS ASAP Online (Learn how to maintain Completed Work without manual action).

Feel free to register for TFS ASAP Online. In case of any questions, don’t hesitate to ask via tfsasaponline@aitgmbh.de.

How to use the VSO Task Board to directly close Tasks and don’t have to think about Remaining Work is a post from: AIT Blog

codefest.at [MS]: Azure Media Services mit dem Azure Media Player konsumieren

Heute wurde der Azure Media Player im Azure-Blog angekündigt.

Announcing Azure Media Player

Der Azure Media Player dient dazu, Media Streams von den Azure Media Services auf verschiedensten Geräten wiederzugeben. Im O-Ton liest sich das so: “Azure Media Player utilizes industry standards, such as HTML5 (MSE/EME) to provide an enriched adaptive streaming experience.“

image

Wichtig:
Der Azure Media Player unterstützt ausschließlich Media Streams von den Azure Media Services.

Unter der Adresse http://aka.ms/azuremediaplayer kann der Azure media Player live ausprobiert werden. Es können sogar eigene Videos (URLs) aus den Azure Media Services durch Einfügen des .ism/manifest files in die URL und “update player” verwendet werden. Hier gehts zur Ankündigung im Blog.

Viel Spaß damit, oder besser: Film ab!

Johannes Renatus: JavaScript IntelliSense mit Visual Studio 2013

Schon oft habe ich versucht mit der IntelliSense von JavaScript und Visual Studio 2013 warm zu werden, meist hat dies aber nicht wirklich funktioniert. Jetzt habe ich mich doch noch einmal damit auseinander gesetzt und es sogar hinbekommen. Dabei ist es eigentlich ganz einfach, wenn man einmal weiß worauf man zu achten hat. Damit die […]

Fabian Deitelhoff: LEGO Mindstorms EV3: Kennenlernworkshop bei der VHS Unna

In letzter Zeit habe ich einige Kurse und Workshops an Volkshochschulen gehalten. Auch erneut einen Kennenlernworkshop zum Thema LEGO Mindstorms EV3 bei der VHS Unna. Eine Wiederholung des Kurses, der im letzten Jahr so gut angekommen ist. Dieses Mal war es am Samstag, den 28. März soweit. Also schon etwas weiter zurück. Aufgrund von Ostern, sowie den vielen anderen Kursen, komme ich aber leider jetzt erst zu einer kleinen Nachbetrachtung.

Der Kurs

Der Kurs ist organisatorisch identisch geblieben. Wir hatten vier Unterrichtseinheiten zu je 45 Minuten mit einer Pause von 15 Minuten zur Verfügung. Angesetzt war der Kurs von 10.00 Uhr bis 13.15 Uhr und bot somit für einen Einsteigerkurs genug Platz für Themen rund um den LEGO Mindstorms EV3. Insgesamt elf Teilnehmer und Teilnehmerinnen hatten sich dazu entschlossen, etwas zum Mindstorms-System zu erfahren.

Inhaltliches

Wie immer beim Kennenlernworkshop war der Inhalt auf Einsteiger zugeschnitten, die bisher noch nie mit dem LEGO Mindstorms System in Berührung gekommen sind. Aber auch Erfahrungen im Bereich Programmierung oder Softwareentwicklung allgemein waren nicht Voraussetzung. Nur einen Computer bedienen, etwas logisches Denken und Spaß an der Sache sind Pflicht. :)

LEGO Mindstorms EV3 - Kennenlernworkshop bei der VHS Unna.

LEGO Mindstorms EV3 – Kennenlernworkshop bei der VHS Unna.

Zu Beginn habe ich es etwas über die Geschichte des Mindstorms, den Zweck und die dahinter stehende Community erzählt. Anschließend ging es um die Komponenten, die Hardware, Software und natürlich auch um die Entwicklungsumgebung und wie damit erste kleinere Programme entwickelt werden können.

LEGO Mindstorms EV3 - Eine praktische Einführung

LEGO Mindstorms EV3 – Eine praktische Einführung

In der zweiten Hälfte waren dann kleinere Aufgaben an der Reihe, die selbstständig gelöst werden mussten. Dieser Teil läuft erfahrungsgemäß sehr gut, da alle Teilnehmer genügend eigene Ideen zur Umsetzung haben. Manchmal läuft es etwas besser mit der Programmierung, manchmal gebe ich ein paar Hilfestellungen mehr. In Zukunft möchte ich hier gerne noch weitere Aufgaben parat haben, die ich auch an die Teilnehmer verteilen kann, so dass die Aufgabenstellung klarer wird.

Fazit

Wie immer hat es mir auch dieses Mal sehr viel Spaß gemacht. Die Gruppe war sehr gut drauf und hat fantastisch mitgearbeitet. Nicht zuletzt sorgt auch die gute Atmosphäre in der VHS Unna für einen angenehmen Kurs. Ich freue mich schon auf die nächsten Kurse sowohl zum LEGO Mindstorms EV3, als auch zu anderen Themen.

Uli Armbruster: Incorrect password or no TrueCrypt volume found

Mein Laptop ist vollständig mit TrueCrypt verschlüsselt. Jedoch konnte die zweite Partition, welche mit genau dem gleichen Passwort verschlüsselt wurde, nicht geladen. Stattdessen erhielt ich folgende Fehlermeldung:

image

Hintergrund ist der, dass ich ein deutsches Tastaturlayout verwende. Nachdem ich mehrere Methoden, wie sie im Netz zu finden sind, vergeblich durchführte, nahm ich eine Abkürzung und stellte einfach das Passwort um. Ab jetzt nutze ich nur noch Zeichen, die sowohl auf der englischen als auch der deutschen Tastatur gleich sind. Stichwort y/z und Konsorten.

Das Ändern des Kennworts ging übrigens in wenigen Sekunden, sodass ihr nicht wie bei der initialen Encryption mehrere Stunden für den Vorgang veranschlagen müsst.


Einsortiert unter:German, Misc Tagged: Security

Ralf Westphal: Konsequente Verlässlichkeit - Promise Like a Pro

Die grundlegenden Kompetenzen, die jeder Softwareentwickler haben sollte sind nach Joel Spolsky: Smart, and Get things done. Dem kann ich nur zustimmen. Und nicht nur für Softwareentwickler gilt dies, würde ich sagen. Es sind die Voraussetzungen für jeden “Wissensarbeiter”, egal ob Programmierer, Tester, Product Owner, Softwarearchitekt, Entwicklungsleiter usw. Wie es mit der Smartness in der

Uli Armbruster: Microsoft TechCamp Week mit Hackathon in Pforzheim

Microsoft und die Medien-IT-Initiative Pforzheim veranstalten im Mai ein TechCamp in Pforzheim. Die Veranstaltungen sind kostenlos, jedoch ist für jeden Tag eine Anmeldung notwendig. Hier findet ihr die direkten Links zu Anmeldung.

imageAufgrund meiner Erfahrung (1,2,3) kann ich speziell den Hackathon in Pforzheim empfehlen. Der ist jedes Mal eine tolle Sache. Danke an Petra von der Medialesson GmbH, die mich darauf aufmerksam gemacht hat.


Einsortiert unter:Events, German Tagged: Community

Norbert Eder: #fotomontag #15

Jeden Montag ein Foto. Der #fotomontag.

Der Schloßberg in Graz hat so einiges zu bieten. Vom Schloßbergplatz führt ein Stollen zu einem Lift, mit dem man zum Uhrturm fahren kann (und sich die 260 Stufen hinauf erspart). Das Farbenspiel in diesem Tunnel ist wirklich toll, aber auch die S/W-Variante hat einiges zu bieten. Das Foto gefällt mir persönlich sehr gut, nur kann ich mich nicht entscheiden, ob es mir in Farbe oder eben in S/W besser gefällt. Deshalb möchte ich beide Varianten zeigen.

Schloßberglift (Farbe)

Schloßberglift (Farbe)

Schloßberglift (S/W)

Schloßberglift (S/W)

Bildinformationen:
18mm
ISO 200
f/11
3,2 Sek.

Welche Variante findest du besser? Oder hast du Verbesserungsvorschläge? Hinterlasse mir doch einen Kommentar.

The post #fotomontag #15 appeared first on Norbert Eder.

Jürgen Gutsch: Pretzel – finished the Blog Migration

Die Migration meines Blogs vom Community Server nach Pretzel ist nun technisch fast abgeschlossen.

Die größter Herausforderung bestand darin, die alten Beiträge sauber aus dem alten System in das neue Markdown-basierte System zu bringen. Auf Codeplex fand ich ein kleines Projekt, dass dafür da war, Blogs über die MetaWeblog PI in das BlogML Format zu exportieren (https://metaweblogtoblogml.codeplex.com/). Ich habe das Projekt nun so angepasst, das statt BlogML, der Output Markdown-Dateien sind die im Pretzel, bzw. Jekyll Format vorliegen (https://github.com/JuergenGutsch/MetaWeblog-To-Mardown-Converter). Da dieses Projekt nur einmalig zum Export verwendet wird, habe ich nicht auf sauberen Code geachtet.  Der Code enthält viele kleine Korrekturen die über einfaches String-Replacement gelöst sind. Zum Beispiel müssen Umlaute korrigiert werden. Auszeichnungen für Codebeispiele müssen von BB-Code ähnlicher Syntax nach Markdown übersetzt werden. Bildpfade müssen ggf. angepasst werden.

Für Codebeispiele kommt nun der clientseitiger Javascript Formatter highlight.js zum Einsatz. Pretzel ist bereits für diesen Formatter ausgelegt, das heißt der generierte HTML Code wird von highlight.js verarbeitet.

Nun müssen noch Bilder aus dem alten System in das neue geholt werden, neu verlinkt werden und der Export ist aus technischer Sicht fertig. Diesen Schritt werde ich nicht automatisieren können.

Nun folgt der aufwendigste Schritt:

Mein Blog ist recht gut Verlinkt und ich werden dafür sorgen müssen, dass die alten Links noch gehen. hier werde ich mich nun zwischen mehreren Möglichkeiten entscheiden müssen.

  • Ich nehme alle Artikel in das neuen Blog und ignoriere die alten Verlinkungen.
    • Solange Stefan Falz das alte Blog online hält existieren die Contents doppelt, wäre aus meiner Sicht kein großes Problem
    • Wenn Stefan meinen Blog löscht führen die alten Links ins leere.
  • Ich nehme nur die neuesten und alle zukünftigen Artikel in den neuen Blog auf. Mache also einen harten Break und starte mein Blog unter neuer URL neu.
    • Sobald Stefan aber mein Blog löscht, sind die alten Beiträge allerdings nicht mehr erreichbar.
    • Die Migration wäre fast umsonst gewesen.
  • Ich nehme alle Artikel in das neue Blog und Bitte Stefan eine Umleitung für mein Blog einzurichten.
    • Die Umleitung funktioniert auch nur so lange wie Stefan das alte System, bzw. den Server online lässt.
    • Alle Anfragen auf http://www.aspnetzone.de/blogs/juergengutsch/ müssten nun auf http://blog.gutsch-online.de/ gehen.
    • Ich müsste dann schauen, wie ich die weiteren Umleitungen der Artikel übernehme, da sich die Pfade auch leicht geändert haben.
    • Letzteres scheint mir das schwierigste, da der Blog auf https://pages.github.com/ gehostet wird und die Möglichkeiten dort nicht so umfangreich sind.

Die RSS Syndication ist kein Problem, da die RSS und Atom Feeds des Blog seit Jahren über Googles Feedburner läuft. Ich ändere also dort nur das Quell-Feed in der Feedburner Verwaltung. Die URL für alle Feed-Abonnenten ändert sich somit nicht.

Schwierig also. Mal sehen. Bis ich eine gute Lösung gefunden habe geht’s mal noch in diesem System weiter :)

Jürgen Gutsch: Working with Git – Part 1

Seit gut zwei Jahren arbeite ich nun fast ausschließlich mit Git, nachdem ich vorher mehrere Jahre mit Mercurial gearbeitet habe war der umstieg nicht allzu schwierig. Heute sind es noch einige alte private Projekte die mit Mercurial laufen. Migrieren möchte ich diese nicht. Warum auch? Mercurial ist genauso gut, für Einsteiger in die verteilten SCM sogar besser, das es eine einfachere API besitzt. Ein seit drei Jahren laufendes privates Projekt, basiert im Backend sogar auf Mercurial zur Sicherung, Versionierung und Verteilung von Daten.

Erst seit ich in Basel bei der YooApps arbeite, bin ich sowohl beruflich als auch privat auf Git umgestiegen. Fazit? Vom Prinzip keinen Unterschied. Wieso auch? Ich halte beide Systeme für gleichwertig. Git bietet lediglich mehr Möglichkeiten, wohingegen Mercurial wesentlich einfacher zu bedienen ist.

Soviel zur Einleitung. Was gibt es zu Kritisieren? Nur eines. Es gibt keine wirklich gute GUI für Git, so wie man es von Mercurial gewöhnt ist. Die hg Workbench ist ein einfach zu bedienendes und übersichtliches zentrales Werkzeug, mit dem man sogar gleichzeitig mehrere Repositories bedienen kann. Git kennt kein solches Werkzeug. Das was mit TortoiseGit mitgeliefert wird, sind mehrere einzelne unabhängige Werkzeuge, die eher umständlich zu bedienen sind. SourceTree von Attlassian kommt der hg Workbench recht nahe, hat sich aber als sehr träge und wesentlich unübersichtlicher herausgestellt. SourceTree habe ich mehrere Monate verwendet, nachdem es aber irgendwann bei großen Workspaces mit vielen Branches und vielen Dateien sehr schnell langsam wird, benutze ich es nun nicht mehr.

Über die Git Integration im Visual Studio habe ich mich bereits geäußert. Obwohl dieses nun wesentlich besser geworden ist, nutze ich SCM Integrationen im Visual Studio generell sehr ungern, weil diese nur das sehen, was das Visual Studio sieht. Das heißt alles was im Solution Explorer sichtbar ist, kann mit diesen integrierten SCM Werkzeugen behandelt werden. Alles was über das Dateiensystem direkt gemacht wird, wird von den Integrationen nicht gesehen. Das Gilt auch für den TFS und VisualSVN und ähnlichen Tools.

Das heißt es bleibt für Git nur die Konsole übrig, bzw. den Cmder. Das ist aus meiner Sicht eine der besten Konsolen, der nicht nur nützliche Linux-Befehle mitbringt, sondern eine Git Integration enthält, welche die Übersicht in der Konsole enorm steigert. Den Cmder nutze ich nun seit sehr langer Zeit als Git Client. Das beste an dieser Konsole, ist allerdings die Nutzung von Ctrl+V um Text, Pfade, Befehle, etc. direkt in die Konsole zu bringen. Die paar Git Befehle die man im Alltag verwendet sind relativ schnell verinnerlicht. Alles andere lässt sich schnell Googlen.


im Cmder wird immer der aktuelle Branch am Ende des aktuellen Ordners angezeigt, wenn es sich um einen Git-Workspace handelt.

Im folgenden Artikel möchte ich beschreiben wie Ich selber und wie wir bei der YooApps mit Git sehr erfolgreich arbeiten.

Uli Armbruster: Vorlage für die Erwiderung von Privatpersonen bei E-Mail-Werbung

Nach meinem ersten Beitrag über Telefonwerbung will ich euch jetzt die Vorlage zur Erwiderung von E-Mail-Werbung geben. Dabei spreche ich in erster Linie von Werbung wie sie z.B. von einem Fitnessstudio oder einer Versicherung kommen kann. Offensichtliche Spam- oder Phising Mails, wie sie für Viagra typisch sind (auf diese sollte man generell nicht antworten, weil es sonst nur noch mehr werden), sind ebenso wenig gemeint wie Newsletter. Bei letzteren muss nach aktueller Gesetzeslage immer auch ein Abmelde-Link mitgeschickt werden, der in der Regel ganz am Ende der E-Mail und in kleiner Schrift (häufig ‘Newsletter abbestellen’) zu finden ist. Sollte dies nicht der Fall sein, ist das klar rechtswidrig.

Ich möchte abschließend noch darauf hinweisen, dass ich weder Jurist noch Datenschutzbeauftragter bin und es sich hierbei lediglich um eine Hilfestellung als Privatperson handelt. Holt euch also im Zweifelsfall bei entsprechenden Stellen Hilfe dazu.

Ich möchte Sie darauf hinweisen, dass ich von Ihnen keinerlei Werbung erhalten möchte. Ihre E-Mail war zudem rechtlich nicht erlaubt, da Ihnen keine (ausdrückliche) Zustimmung meinerseits vorlag. Ihre Werbung wird demnach, gemäß §7 Abs. 2 Nr. 3 UWG, als unzumutbare Belästigung angesehen.

Hiermit fordere ich Sie auf, wie im § 19 BDSG Abs. 1 vorgesehen, mir mitzuteilen, welche Daten Sie über mich gespeichert haben, aus welcher Quelle Sie diese Daten haben und an wen Sie diese Daten weitergegeben haben.

Des Weiteren erwarte ich, dass gemäß § 20 BDSG Abs. 2 meine Daten gelöscht werden. Wenn dies aufgrund eines Gesetzes nicht möglich ist, sind die Daten zu sperren (vgl. §20 BDSG Abs. 3).

Aus den gegebenen Gründen bitte ich Sie deshalb, mir jegliche Art von Werbung (E-Mail, Telefon, Post) nicht mehr zu schicken und mich aus Ihrem System zu entfernen.

Es gibt dedizierte Listen im Internet, in welche man sich eintragen kann, um von den Werbetreibenden nicht adressiert zu werden. Jedoch werden diese Verzeichnisse nicht sonderlich beachtet. In einem späteren Beiträge werde ich dazu einen Link veröffentlichen.


Einsortiert unter:German, Misc Tagged: Datenschutz

Fabian Deitelhoff: AntMe: Ferienworkshop bei der VHS Unna

Neben meinen Bestrebungen, Kindern, Jugendlichen und Erwachsenen den LEGO Mindstorms EV3 in Volkshochschulen näher zu bringen, versuche ich mich auch an Themen, die etwas mehr in Richtung Softwareentwicklung gehen. Natürlich ist das beim LEGO Mindstorms auch der Fall. Denn ohne Programmierung tut sich bei den EV3-Modellen nicht viel bis gar nichts.

Mit etwas mehr Softwareentwicklung meine ich aber hauptsächlich eine andere Sprache. Die grafische Programmierung beim Mindstorms ist recht abstrakt. Mit meinem ersten AntMe-Kurs bei der VHS Unna habe ich die Richtung zu C# und einer gänzlich anderen Aufgabenstellung verschoben. Jetzt geht es mehr um Syntax, gemischt mit ein wenig künstlicher Intelligenz und Schwarmverhalten, sowie um Tools wie Visual Studio und natürlich AntMe an sich.

Der Kurs

Teilgenommen haben fünf junge Menschen im Alter von 10 bis 14 Jahren, wenn ich mich da noch recht erinnere. Alle ohne wesentliche Vorkenntnisse im Bereich der Softwareentwicklung. Weder mit C# noch mit einer anderen Sprache. Einige kannten Scratch, andere hatten schon mit dem LEGO Mindstorms EV3 Erfahrungen sammeln können, was das Umsetzen von Ideen in einen Programmablauf angeht. Manche hatten gar keine Erfahrungen.

VHS-Kurs "Programmieren lernen mit AntMe!"

VHS-Kurs “Programmieren lernen mit AntMe!”

Ein paar Kenntnisse in Richtung Programmablauf oder ähnliches sind natürlich wertvoll, wenn es um die Entwicklung von Algorithmen aller Art geht. Allerdings ist AntMe! so einfach gestaltet, dass die Funktionsweise schnell verstanden wird und somit auch Anfänger keinerlei Probleme bei der Einarbeitung haben.

Der Inhalt

Daher war es keine große Überraschung, dass sich die Teilnehmer zügig mit AntMe! und Visual Studio befassen konnten und auch verstanden haben, worum es geht.

Logo von AntMe!Natürlich ist die Programmierung an sich erst einmal eine kleine Hürde. Alle Zeichen müssen korrekt eingegeben werden und eine Programmiersprache wie C# meckert selbstverständlich auch bei jeder kleinsten Abweichung. Und trotzdem haben sich alle schnell an diese neuen Anforderungen gewöhnt und sie hervorragend gemeistert, nachdem ich ein paar Grundlagen zur Syntax und Visual Studio gezeigt hatte.

Konkret ging es inhaltlich um viele Dinge aus der Informatik beziehungsweise dem Berufsalltag eines Informatikers oder Softwareentwicklers. So festgeschrieben ist das in unserer Branche ja nicht. Einige der Themenschwerpunkte waren: Programmierung, Tools, Automaten, Zustandsdiagramme, analytisches Denken, Lösungskompetenz, sowie Teamarbeit und Kommunikation.

Alle Themen wurden dabei anhand der Ameisen beziehungsweisen deren gewünschten Verhalten eingeführt. Am Anfang habe ich das AntMe! Programm erklärt und zwei, drei Kleinigkeiten vorgeführt, so dass alle verstehen konnten, wie beispielsweise eine Aktion ausgeführt werden kann und wie das mit den Simulationen funktioniert. Danach war aber eigenständiges Arbeiten angesagt. Ich habe hin und wieder Anregungen eingestreut, was die Ameisen noch machen könnten oder wo es Potenzial für Verbesserungen gibt. Allerdings kamen die Teilnehmer schon selbst auf die meisten Verbesserungen. :)

Einer dieser coolen Momente war, als der jüngste Teilnehmer auf den Monitor eines anderen Teilnehmers zeigte und meinte, er hätte dort einen Programmierfehler. Es würde ein “if” fehlen. Gemeint war eine Stelle wie die folgende.

public override void Sieht(Zucker zucker)
{
    GeheZuZiel(zucker);
}

public override void Sieht(Zucker zucker)
{
    if(Ziel == null)
    { 
        GeheZuZiel(zucker);
    }
}

Die zweite Variante ist korrekt, da sich in diesem Fall eine Ameise nur zu einem Zuckerhaufen bewegt, wenn kein Ziel vorhanden ist, also beispielsweise die Ameise nicht schon am Zuckerhaufen ist oder vielleicht sogar einen weiteren sieht. Solche Stolperfallen hatten die Teilnehmer sehr schnell drauf und wussten damit umzugehen. Auch in anderen Situationen. Mit gerade einmal 10 Jahren und nach wenigen Stunden mit C# und AntMe!. :)

Ameisen vs. Ameisen

Am besten gefallen haben mir die kleinen Turniere, die als Jeder gegen Jeden-Simulationen aufgebaut waren. :) Dabei sind alle Ameisenvölker, natürlich auch mein eigenes, über 10.000 Iterationen in drei Durchläufen, gegeneinander angetreten. Danach wurde eine Rangliste anhand der Gesamtpunkte aufgestellt und der letzte musste leider für die nächste Runde aussetzen. So ging es weiter, bis die ersten drei Plätze ermittelt waren.

Nach den drei Durchläufen durften Änderungen am Ameisenvolk vorgenommen werden, um vorhandene Schwächen auszumerzen oder aktuelle Stärken weiter zu verbessern. Meistens haben diese Verbesserungen auch gegriffen und das Ergebnis wurde tatsächlich etwas besser. Ein Denk- oder Programmierfehler hat aber auch so manches Mal etwas ganz anderes verursacht, als das gewünscht war. Wie im echten Leben. ;)

Schwierigkeiten

Schwer finde ich es, Konzepte wie die objektorientierte Programmierung und alles was damit zusammenhängt einzuführen. Beispielsweise Überladung und Vererbung. Alles Konzepte, die AntMe! beziehungsweise die implementierten Ameisen verwenden. Den Grund dafür zu vermitteln finde ich aber durchaus anspruchsvoll. Bis auf Klassen an sich und Methoden habe ich während den beiden Kurstagen auch keinerlei Dinge angesprochen. Ich fand das reichte an Grundlagen aus. Für zukünftige Kurse oder welche mit mehr Zeit, müsste ich mir noch mal etwas dazu überlegen.

Fazit

Mir hat der Kurs viel Spaß gemacht und so wie mir die Teilnehmer Feedback gegeben haben, ihnen auch. :) Ich hoffe ich kann diese Art von Kursen in Zukunft öfters durchführen. Vielleicht auch im Rahmen einer AG oder ähnliches an einer Schule. Denn ich finde AntMe! als Einführung in die Welt der Programmierung/Softwareentwicklung, beziehungsweise allgemein für Informatik-Themen, wirklich sehr gut geeignet.

Ralf Westphal: Die IODA Architektur

Über die Jahre haben einige grundlegende Architektmodelle um unsere Gunst gekämpft. Mir fallen ein in chronologischer Reihenfolge ein: MVC (Ja, das rechne ich zu Architekturmodellen, weil es Leute gibt die sagen, "Unsere Software hat eine MVC-Architektur.) das Schichtenmodell Pat Hellands Executants, Emissaries und Fiefdoms Alistair Cockburnss Hexagonal Architecture aka Ports-and-Adapters

Golo Roden: Ich kenne was, was Du nicht kennst: Passport

Express gilt als das De-Facto-Framework zur Entwicklung serverseitiger Webanwendungen auf Basis von Node.js, enthält aber keine eingebaute Lösung für Authentifizierung. Das Middleware-Modul Passport schafft Abhilfe.

codefest.at [MS]: Was Spannendes, was zum Rumspielen und was zum Naschen!! …

… Was hättet Ihr denn Lieber?

  • Die neuesten Technologien und Gadgets aus dem Microsoft Hexenkessel erleben?
  • Eine Woche vor dem offiziellem Verkaufsstart exklusiv die neuesten Surface Geräte ausprobieren?
  • Mit Popcorn und Cola im Kreise gleichgesinnter einen interessanten Abend verbringen?

Oder am besten alles auf einmal?

Kommt zum kostenlosen //build Keynote-Streaming in einem Kino in Eurer Nähe und verbindet das Angenehme mit dem Nützlichen!

Live dabei sein mit dem Microsoft //build Keynote-Streaming!

Vom 29. April bis zum 1. Mai findet auch heuer wieder die //build statt. Für alle Entwickler ist die //build ein "Must Event". Seit Anbeginn ist diese Veranstaltung in kürzester Zeit ausverkauft ist. So auch heuer wieder.

Damit Ihr zumindest die Keynote im //build Feeling erleben könnt laden wir Euch ein mit uns gemeinsam die Keynote in Kinos in Wien, Linz und Graz zu erleben!

Was Euch als Besucher erwartet:

  • Die Highlights der restlos ausverkauften //build 2015 Konferenz live aus San Francisco.
  • Ein anschließender Abendfilm inklusive Popcorn und Getränk.
  • exklusiv in Wien: Das neue Surface 3 zum Anfassen und Ausprobieren, schon vor dem offiziellen Österreich-Release!

Also rasch zum kostenlosen //build Keynote-Streaming anmelden, und wir wünschen Euch schon jetzt einen interessanten und unterhaltsamen Kinoabend!

Wo & Wann: 29. April 2015 am 17:15 Uhr in den folgenden Kinos:

Bei Fragen, Wünschen und Komplikationen aller Art erreicht Ihr mich wie gewohnt unter meiner E-Mail Adresse.

Wir sehen uns im Kino!

Gerhard Göschl, Marketing Leiter - IT-Spezialisten und Software Entwickler

Microsoft Österreich GmbH
Gerhard.Goeschl@Microsoft.com

Uli Armbruster: Vorlage für die Erwiderung von Privatpersonen bei Telefonwerbung

In den folgenden Tagen werde ich Vorlagen für schriftliche Erwiderungen auf Werbung jeglicher Art veröffentlichen. Dazu gehören ungewünschte E-Mails, Anrufe und Briefe sowohl im privaten als auch im beruflichen Umfeld.

Heute starte ich mit Telefonwerbung im privaten Umfeld. Wenn z.B. jemand bei euch zuhause anruft um ein Gewinnspiel zu bewerben, ohne dass eine Einwilligung eurerseits vorliegt, dann könnt den folgenden Text verwenden.

Ich möchte abschließend noch darauf hinweisen, dass ich weder Jurist noch Datenschutzbeauftragter bin und es sich hierbei lediglich um eine Hilfestellung als Privatperson handelt. Holt euch also im Zweifelsfall bei entsprechenden Stellen Hilfe dazu.

 

Ich möchte Sie darauf hinweisen, dass ich von Ihnen keinerlei Werbung erhalten möchte. Ihr Anruf war zudem rechtlich nicht erlaubt, da Ihnen keine (ausdrückliche) Zustimmung meinerseits vorlag und Ihr Anruf demnach, gemäß §7 Abs. 2 UWG, als unzumutbare Belästigung angesehen wird.

Hiermit fordere ich Sie auf, wie im § 19 BDSG Abs. 1 vorgesehen, mir mitzuteilen, welche Daten Sie über mich gespeichert haben, aus welcher Quelle Sie diese Daten haben und an wen Sie diese Daten weitergegeben haben.

Des Weiteren erwarte ich, dass, gemäß § 20 BDSG Abs. 2, meine Daten gelöscht werden. Wenn dies aufgrund eines Gesetzes nicht möglich ist, sind die Daten zu sperren (vgl. §20 BDSG Abs. 3).

Aus den gegebenen Gründen bitte ich Sie deshalb, mir jegliche Art von Werbung (E-Mail, Telefon, Post) nicht mehr zu schicken und mich aus Ihrem System zu entfernen.

 

Unerlaubte Telefonwerbung bleibt ÄrgernisAktualisierung vom 11.04.2015:

Ausgerechnet heute bin ich in der News-App von ZDF auf folgende Meldung gestoßen (siehe Screenshot). Im Anschluss an die Blogserie werde ich deshalb noch einen weiteren Artikel mit Anlaufstellen veröffentlichen, für den Fall, dass die Unternehmen die Werbung nicht unterlassen. Sieht man sich die hohe Zahl schriftliche Beschwerden an, wird deutlich, dass das Thema durchaus Anklang findet. Wenn – subjektiv aus meiner Sicht geschätzt – nur jeder 10 Verbraucher eine Nachricht an die Bundesnetzagentur schreibt, so sprechen wir von über 250.000 Werbeanrufen.

 

 


Einsortiert unter:German, Misc Tagged: Datenschutz

Ralf Westphal: Die Selbstlern-Challenge - Retrospektive

Zehn Wochen sind wie im Flug vergangen, seit ich zur Teilnahme an einer Selbstlern-Challenge eingeladen hatte. Das Angebot Die Herausforderung war, sich selbstständig über einen Zeitraum von 10 Wochen in das Thema Flow Design & Co einzuarbeiten. Einzige Bedingung: Als Dokumentation des Dranbleibens am Thema sollte mir jede Woche eine Frage per Email geschickt werden - die ich dann

Martin Richter: Stark verzögertes Öffnen von Projekten in Visual Studio 2013

In der letzten Zeit hatte ich immer mal wieder so einen komischen Effekt, dass ich VS-2013 gestartet habe und beim Öffnen einer Solution auf einmal nur noch die Eieruhr (Blue Circle of Death) zu sehen war. In der Anzeige stand meisten das irgend ein Projekt N vom M zu laden wäre. :sad:
Als mir das das erste mal passierte habe ich oft den Visual Studio Prozess brachial beendet, neu gestartet und dann ging es oft. Aber nicht immer. Wenn ich lang genug gewartet hatte wurde letzten Endes die Projekte immer geladen.

Weil mich das irgendwann nervte habe ich mal versucht Visual Studio selbst zu debuggen. Die Threads die aktiv waren, hatten immer was mit dem Team Foundation Server zu tun. Bald merkte ich, dass lokale Projekte nie betroffen waren sondern immer nur Solutions, die auch auf unserem zentralen TFS Server lagen.

Der nächste Schritt :idea: war dann beim nächsten Hänger mal die Firewall und den Netzwerkschutz abzuschalten. Wir verwenden hier seit Jahren Symantec Endpoint Protection (aktuell 12.1 RU5). Bingo !!! :) Kaum, dass ich die Firewall abgeschaltet hatte lief, das Laden des Projektes sofort durch.

Entsprechend haben wir in den Firewall Einstellungen für Visual Studio jetzt eine Ausnahme Regel definiert und seit dem keine Probleme mehr. :mrgreen:

 


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)

Manfred Steyer: Validierungsframework mit Dekoratoren und Annotationen in TypeScript 1.5

TypeScript 1.5 führt neben der Modul-Grammatik von EcmaScript-6 und anderen netten Neuerungen auch das Konzept der Dekoratoren ein. Dabei handelt es sich um Funktionen, mit denen andere Sprachkonstrukte annotiert werden können. Zu diesen Konstrukten zählen Funktionen, Klassen aber auch Eigenschaften. JavaScript ruft die Dekorator-Funktionen beim Start eines Skripts auf und übergibt an diese die annotierten Konstrukte. Der Dekorator hat dann die Möglichkeit, diese Konstrukte zu erweitern oder durch andere Konstrukte zu ersetzen. Einen Überblick zu diesem Sprachkonstrukt, das auch in Angular 2 zum Einsatz kommen wird, findet man unter [1] und [2]. Dieser Beitrag demonstriert anhand der aktuell vorliegenden Alpha-Version von TypeScript den Einsatz von Dekoratoren am Beispiel eines einfachen Validierungsframeworks. Die Idee ist es, für Klassen sowie deren Eigenschaften mittels Annotationen Validierungsregeln festzulegen. Das nachfolgende Beispiel zeigt eine solche Klasse:

@Validate(h => h.minPrice <= h.maxPrice, "min < max")
class Hotel {

    @Required
    name: string;

    @MinValue(0, "Min: 3")
    @MaxValue(7, "Max: 7")
    ranking: number;

    minPrice: number;
    maxPrice: number;
}

Im gezeigten Beispiel validiert die Annotation @Required ein Pflichtfeld und @MinValue sowie @MaxValue prüfen gegen eine festgelegte untere bzw. obere Schranke. Diese Schranken sowie die Fehlermeldungen nehmen sie als Parameter entgegen. Die Annotation @Validate wird im Gegensatz zu den anderen Annotationen auf eine Klasse angewandt. Sie erhält einen Lambda-Ausdruck für die Validierung und ebenfalls eine Fehlermeldung. Zur Realisierung der Validierung soll jedes zu Validierende Objekt ein Array __validators mit Validierungsfunktionen erhalten. Jede Validierungsfunktion prüft einen Aspekt des Objektes und retourniert im Fehlerfell eine Fehlermeldung; ansonsten liefert sie null zurück. Für diese Aufgabe nutzt das hier betrachtete Beispiel die Hilfs-Funktion addValidator:

function addValidator(target, fn, errorMessage) {

    var validationFn = () => !fn() ? errorMessage : null;

    if (!target.__validators) {
        target.__validators = [];
    }

    target.__validators.push(validationFn);

}

Diese Funktion nimmt das zu validierende Objekt, eine Funktion zum Validieren und eine eventuelle Fehlermeldung entgegen. Die übergebene Funktion liefert per Definition true, wenn die durchgeführte Validierung erfolgreich war; ansonsten false. Damit erstellt addValidator eine Validierungsfunktion, die im Fehlerfall die Fehlermeldung retourniert, und platziert diese in der Variable validationFn. Anschließend prüft addValidator, ob das Objekt bereits ein Array __validators aufweist und fügt dieses bei Bedarf hinzu. Danach hinterlegt sie die Validierungsfunktion in diesem Array. Eine erste Version des Dekorators Required findet sich im nächsten Beispiel. Da dieser Dekorator auf Attribute angewendet wird, bekommt er per Definition das betroffene Objekt und den Namen der Eigenschaft übergeben. Er erstellt eine Funktion, welche ein Pflichtfeld validiert. Diese prüft, ob der zu prüfende Wert null oder undefined ist. Anschließend registriert Required diese Funktion zusammen mit einer einfachen Fehlermeldung als Validierungsfunktion. Dazu kommt die zuvor betrachtete Funktion addValidator zum Einsatz.

function Required(target, name) {
    var fn = () => target[name] !== null && typeof target[name] !== "undefined";
    var errorMessage = name + " is required!";
    addValidator(target, fn, errorMessage);
}

Weniger schön am letzten Beispiel ist die Tatsache, dass die Fehlermeldung hardcordiert hinterlegt wurde. Das kann umgangen werden, indem man eine Funktion vorsieht, die den Dekorator erzeugt. Solche Factory-Funktionen können ebenso wie Dekoratoren in Form von Annotationen im Quellcode platziert werden. Das nachfolgende Beispiel demonstriert dies. Es zeigt zwei Factory-Funktionen, die Parameter zum Steuern der Validierung entgegen nehmen und jeweils eine Dekorator-Funktion mit der gewohnten Signatur retournieren:

function MinValue(min, errorMessage) {

    return function (target, name) {
        var val = () => target[name] >= min;
        addValidator(target, val, errorMessage);
    };
}

function MaxValue(max, errorMessage) {
    return function (target, name) {
        var val = () => target[name] <= max;
        addValidator(target, val, errorMessage);
    };
}

Die Factory-Funktion für die Annotation Validate gestaltet sich ähnlich: function Validate(fn, errorMessage) { return function (target) { addValidator(target.prototype, () => fn(target), errorMessage); }; } Zum Validieren nimmt sie einen Lambda-Ausdruck sowie eine Fehlermeldung entgegen. Der erzeugte Decorator nimmt wie gewohnt das betroffene Konstrukt entgegen. Da Validate zum Annotieren von Klassen gedacht ist, handelt es sich hierbei nicht um ein Objekt, sondern um die jeweilige Klasse bzw. Konstruktor-Funktion. Ein Parameter für den Namen der markierten Eigenschaft ist aus demselben Grund hinfällig. Damit addValidate die Validierungsfunktion zu sämtlichen aus der Klasse erzeugten Objekten hinzufügt, übergibt das betrachtete Beispiel den Prototyp dieser Klasse an addValidator. Nun benötigt man nur noch ein Stück Code, welches sämtliche Validierungsfunktionen eines Objektes aufruft und die so erhaltenen Fehlermeldungen einsammelt. Das nächste Beispiel zeigt ein eine Klasse Validator, welche sich um diese Aufgabe kümmert:

class Validator {

    static validate(obj) {

        var errMessages = [];

        if (!obj || !obj.__validators) return errMessages;

        for (var fn of obj.__validators) {
            var errMessage = fn();

            if (errMessage) {
                errMessages.push(errMessage);
            }
        }

        return errMessages;
    }
}

Zum Testen der Implementierung kann man die eingangs gezeigte Klasse zum Beispiel instanziieren und an Validator.validate übergeben:

var hotel = new Hotel();
hotel.name = null;
hotel.ranking = 99;
hotel.minPrice = 120;
hotel.maxPrice = 80;


var err = Validator.validate(hotel);

if (err.length > 0) {
    alert(err.join("\n"));
}
else {
    alert("No errors!");
}

Links

Manfred Steyer: TypeScript 1.5 Alpha in Visual Studio installieren

Seit einigen Tagen liegt eine Alpha-Version von TypeScript 1.5 vor. Eines der Highlights dieser neuen Version ist die Unterstützung für die EcmaScript-6-basierte Module. Ein weiteres Highlight ist das Konzept der Dekoratoren. Dabei handelt es sich um einen Vorschlag [1, 2] zur Integration von Annotationen in EcmaScript [1, 2]. Das Ziel davon ist es, bestehenden Code durch das Hinterlegen von Metadaten zu erweitern. Angular 2 wird dieses Konzept nutzen und es ist davon auszugehen, dass auch andere Frameworks davon Gebrauch machen werden, zumal sich analoge Konzepte in Sprachen ebenfalls einer großen Beliebtheit erfreuen. Für TypeScript 1.5 Alpha steht ein Sublime-Text-Plugin zur Verfügung. Dieses findet man inkl. einer Installationsanleitung unter [3]. Die vorliegende Alpha-Version kann jedoch auch mit Visual Studio 2015 (CTP) und Visual Studio 2013 genutzt werden. Um TypeScript 1.5 Alpha in Visual Studio einzurichten, ist es zunächst via Git zu beziehen:

git clone github.com/Microsoft/TypeScript

Anschließend führt man noch im auf diese Weise erhaltenen Verzeichnis das Powershell-Skript VSDevMode.ps1 aus. Für die Installation in Visual Studio 2015 (CTP) ist an den Parameter vsVersion der Wert 14 zu übergeben; für die Installation in Visual Studio 2013 hingegen der 12:

powershell
.\scripts\VSDevMode.ps1 -enableDevMode -vsVersion 14 -tsScript .\bin
exit

Hat alles geklappt, bietet Visual Studio innerhalb von .ts-Dateien Intellisense für TypeScript 1.5 an und auch beim Kompilieren kommt dann diese Alpha-Version zum Einsatz.

Links

Daniel Schädler: ASP.NET MVC 5 Paging selber implementiert

Bei meinem aktuellen Projekt, wollte ich das Paging in einer MVC Applikation selber, ohne Mithilfe der NuGet PagedList for MVC, realisieren.

Zuerst der Reihe nach

  1. Wie wird die erste Seite aufgerufen?
  2. Wie werden dann die folgenden Seiten aufgerufen?

Wie wird die erste Seite aufgerufen?

Zuerst schauen wir uns den HTML Markup des Linkes an, bei welchem wir zur entsprechenden Seite navigieren.


Wie ihr seht ist dass ein ganz normaler Querystring über http

Die Seite wird dann über folgende ActionMethode aufgerufen, wie auch die Seiten die dann folgen. Zum Beispiel Seite 2 etc.

Wie werden dann die folgenden Seiten aufgerufen?

            int toalPageCount = (context.Set<Skater>().Where(skater => skater.IsActive && skater.IsSEV).OrderBy(skater => skater.Lastname).Count() / 10);
            int pageCounter = 0;

            Dictionary<int, List<SkaterDTO>> pages = new Dictionary<int, List<SkaterDTO>>();
            List<SkaterDTO> DTO = new List<SkaterDTO>();                        

            if (selectedPage == 1)
            {
                context.Set<Skater>().OrderBy(skater => skater.Lastname).Where(skater => skater.IsActive && skater.IsSEV).Take(10).ToList().ForEach(skater =>
                {
                    var vm = new SkaterDTO(skater);
                    DTO.Add(vm);
                });
                pages.Add(toalPageCount, DTO.ToList());
                pageCounter++;                    
            }
            else if (selectedPage > 1)
            {
                if (selectedPage == toalPageCount)
                {
                    context.Set<Skater>().OrderByDescending(skater => skater.Lastname).Where(skater => skater.IsActive && skater.IsSEV).Take(10).ToList().ForEach(skater =>
                    {
                        var vm = new SkaterDTO(skater);
                        DTO.Add(vm);
                    });
                }
                else
                {
                    context.Set<Skater>().OrderBy(skater => skater.Lastname).Where(skater => skater.IsActive && skater.IsSEV).Skip(selectedPage * 10).Take(10).ToList().ForEach(skater =>
                    {
                        var vm = new SkaterDTO(skater);
                        DTO.Add(vm);
                    });
                }
                pages.Add(toalPageCount, DTO.ToList());
                pageCounter++;                                        
            }
                       

            return PartialView("Skaters", pages);

Die HTML Seite für die Darstellung des Resultates sieht dann wie folgt aus:

@model System.Collections.Generic.Dictionary<int, System.Collections.Generic.List<EislaufSektionWebUI.DTO.SkaterDTO>>

@{
    ViewBag.Title = "Läufer(innen)";
    Layout = "~/Views/Shared/_LayoutPage.cshtml";
}

@Html.ActionLink("Zurück", "Welcome", "Home")

<table class="table table-responsive table-bordered table-hover">

        <thead>
            <tr>
                <th>
                    Vorname
                </th>
                <th>
                    Name
                </th>
                <th>
                    Bestandene Tests
                </th>
                <th>
                    SEV
                </th>
                <th>
                    Geburtsdatum
                </th>
            </tr>
        </thead>
        <tbody>
            @{               
                var currentPage = int.Parse(HttpContext.Current.Request.QueryString["selectedPage"]);
                foreach (var skater in Model[currentPage-1].ToList())
                {
                    <tr>
                        <td>
                            @skater.Firstname

                        </td>
                        <td>
                            @skater.Lastname
                        </td>
                        <td>
                            @skater.CertificationLevel
                        </td>
                        <td>
                            @skater.IsSEV
                        </td>
                        <td>
                            @skater.DateOfBirth
                        </td>
                    </tr>
                }
            }
        </tbody>
    </table>

<nav>
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        @{
            foreach (var key in Model.Keys)
            {
                var number = key + 1;
                <li>
                    <a href="/Person/GetSkaters?selectedPage=@number">@number</a>
                </li>
            }
        }
        <li>
            <a href="#" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</nav>

Die Twitter Bootstrap “pagination” Links werden dann wie folgt generiert:

<nav>
    <ul class="pagination">
        <li>
            <a href="#" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        @{
            foreach (var key in Model.Keys)
            {
                var number = key + 1;
                <li>
                    <a href="/Person/GetSkaters?selectedPage=@number">@number</a>
                </li>
            }
        }
        <li>
            <a href="#" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
    </ul>
</nav>

Ich hoffe euch hat der Beitrag gefallen und freue mich über Rückmeldungen oder konstruktive Kritik.


Manfred Steyer: Eindrücke vom IT-Visions Infotag 2015 in Essen

Nachfolgend ein paar Eindrücke von unserem gut besuchten Infotag in Essen. Wie jedes Jahr haben wir die Gelegenheit genutzt, um uns mit unseren Kunden und Interessenten über aktuelle Entwicklungen im .NET-Umfeld zu unterhalten.

Wer den Infotag versäumt hat, hat am 11. 5. im München noch einmal die Chance, dabei zu sein. Infos dazu findet man unter [1].

[1] http://www.it-visions.de/produkte/vortragsdetails.aspx?v=8035





Sven Hubert: Iterationen anlegen leicht gemacht: Automatisches Erzeugen von Iterationen mit Hilfe von Power Shell

Um im TFS den zeitlichen Verlauf von Projekten in Form von z.B. Sprints oder Iterationen abzubilden wird der Iterationspfad verwendet. Das manuelle Anlegen der einzelnen Iterationen für einen längeren Zeitraum kann jedoch zu einer aufwendigen Aufgabe werden, da für jede Iteration mindestens der Name sowie das Start- und Enddatum gesetzt werden sollte. image

 

 

 

 

 

 

 

 

 

 

 

Um diesen administrativen Aufwand einzusparen und eine flexible Iterationsstruktur zu erstellen, die Iterationen verschiedener Längen zulässt, empfiehlt es sich diesen Prozess mit Hilfe eines Power Shell Skripts zu automatisieren. Ziel ist es also am Ende nur noch die Informationen über das jeweilige Projekt sowie den Zeitraum anpassen zu müssen, für welchen Iterationen erstellt werden sollen.

Der logische Aufbau solch eines Skripts lässt sich in vier Teile unterteilen. Im ersten Teil werden zunächst alle benötigten .NET Assemblies geladen. Dazu ist es notwendig im Vorhinein die beiden Dlls “Microsoft.TeamFoundation.Client.dll” und “Microsoft.TeamFoundation.Common.dll”, welche sich im Installationsverzeichnis des TFS befinden, in einem  lokalen Verzeichnis abzuspeichern. Erstere stellt die APIs zur Verfügung, um sich zum TFS zu verbinden und um auf Daten aus Team  Projekt Collections und Team Projekten zugreifen zu können. Daran anschließend muss der Pfad, welcher die Dlls beinhaltet, entsprechend angepasst werden.

image

Im zweiten Teil des Skripts befinden sich alle Commandlets, welche mit Funktionalitäten des TFS im Zusammenhang stehen. Hier werden beispielsweise  Funktionen definiert, um die entsprechenden TFS Services zu erhalten, Informationen über ein Teamprojekt zu extrahieren oder eben auch um eine neue Iteration zu erzeugen.

image

Der dritte Teil enthält alle Commandlets, welche zur Berechnung der einzelnen Iterationsdaten notwendig sind, d.h. alle zeitbezogene Funktionen. Für den angegebenen Zeitraum werden die Start- und Enddaten aller Iterationen berechnet, sodass ein Iterationsbaum entsteht der in Quartale, Monate, Zwei-Wochen-Zeiträume, sowie einzelne Wochen gegliedert ist.

Der große Vorteil dieser Vorgehensweise liegt in der variablen Iterationslänge. So kann jedes Team innerhalb eines Teamprojektes separat entscheiden auf welcher Ebene des Iterationsbaumes es arbeiten möchte, d.h. jedes Team kann sich auf eine unterschiedliche Iterationsdauer innerhalb eines gemeinsamen Iterationsbaumes festlegen.

SNAGHTML520d8af

Schließlich findet im vierten Teil des Scripts die eigentliche Ausführung des Programms durch Aufrufen der in den vorhergehenden beiden Teilen definierten Commandlets statt. Um das Skript für eigene Zwecke anzupassen muss an dieser Stelle der Zeitraum sowie die URL der Collection und das Projekt eingetragen werden, für welches die Iterationen erzeugt werden sollen.

SNAGHTML51b08f3

Nicht zuletzt kann nun das Skript ausgeführt werden und die Iterationen werden wie gewünscht für das angegebene Teamprojekt erzeugt. Hat man dieses Skript einmal erfolgreich implementiert, so kann es mit nur wenigen Anpassungen für jedes Teamprojekt eingesetzt werden und erspart damit viel Zeit.

Das vollständige Script ist zu finden unter: CreateIterations.zip

Besonderer Dank an dieser Stelle noch an Martin Hinshelwood (MrHinsh), der mit seinem Blogbeitrag PowerShell TFS2013 API#1 – Get TFSCollection and TFS Service einen guten Einstieg in das Thema PowerShell und TFS liefert und einige nützliche Commandlets, wie z.B. Get-TfsCollection, zur Verfügung stellt.

Iterationen anlegen leicht gemacht: Automatisches Erzeugen von Iterationen mit Hilfe von Power Shell is a post from: AIT Blog

Mario Priebe: BASTA! 2015 – Konferenz für .NET, Windows & JavaScript

BASTA_Herbst_2015_Leaderboard_28841_v9
Mo, 28.09.2015 bis Fr, 02.10.2015
Rheingoldhalle, Mainz

Die BASTA! ist die führende unabhängige Konferenz für Microsoft-Technologien im deutschsprachigen Raum. Durch ihre einmalige Expertendichte, die Aktualität sowie ausgeprägte Praxisrelevanz gehört sie zu den jährlichen Pflichtterminen für Windows- und .NET-Entwickler, Architekten und Projektleiter. Das Konferenzprogramm umfasst die immer größere werdende Technologieplattform der Microsoft-Welt – und darüber hinaus.
Mit über 130 Sessions, Workshops und Keynotes bietet die BASTA! eine Informationsfülle, die ihresgleichen sucht. Hinzu kommen die professionelle Organisation, die vielfältigen Networking-Möglichkeiten sowie das angenehme Ambiente, die die BASTA! zu einem einzigartigen Erlebnis machen.

Frühbucherhighlights

• Workshop-Tag For Free: Bei Anmeldung für 3 Konferenztage bis 7. Mai erhalten Sie einen Power-Workshop-Tag Ihrer Wahl kostenfrei.
• Frühbucherpreise: Sparen Sie bis zu 400 Euro.
• Kollegenrabatt: Mit 3+ Kollegen anmelden und 10 % extra sparen.
• Extra Specials: Freelancer und Mitarbeiter von wissenschaftlichen Einrichtungen erhalten bei uns individuelle Sonderkonditionen – bitte schreiben Sie uns eine Mail an contact@basta.net

Nähere Infos zur BASTA! bekommen Sie unter: www.basta.net

Jens Häupel [MS]: Visual Studio Enterprise 2015

.. wird der Nachfolger von Visual Studio Premium 2013 und Visual Studio Ultimate 2013 werden. Es wird als Visual Studio Enterprise 2015 mit MSDN verkauft werden und enthält alles, was die bisherige Ultimate Edition mit MSDN beinhaltete plus die neuen Features von Visual Studio 2015. Die Versionen Premium und Ultimate wird es nicht mehr geben.

Alle Abonnenten von Visual Studio Premium mit MSDN werden automatisch und kostenlos auf Visual Studio Enterprise 2015 gehoben, sobald die Version fertig ist. Visual Studio Ultimate mit MSDN Abonnenten werden ebenfalls auf diese Version umgestellt.

Sonderangebot:

  • Im Mai und Juni werden alle anderen Upgrade-Möglichkeiten zu Visual Studio Enterprise 2015 mit MSDN mit 50% Discount angeboten.
  • Alle Abonnenten von Visual Studio Premium mit MSDN erhalten zum RTM von Version 2015 automatisch und kostenlos ein Update auf Visual Studio Enterprise mit MSDN (für den Rest der Abo-Zeit)
  • Zum 1. Mai werden die Preise für Visual Studio Ultimate with MSDN an die von Visual Studio Enterprise with MSDN angepasst (Preisreduktion)


Visual Studio Community 2015

wird auch weiterhin eine freie IDE für non-Enterprise Entwicklung sein. Des Weiteren wird es auch Visual Studio Express 2015 Editionen geben.

 

Blog: Announcing the Visual Studio 2015 Product Lineup

Ralf Westphal: Entwickeln im Uhrzeigersinn

Was ist der Unterschied zwischen Software Craftsman und Software Engineer? Darüber kann man natürlich lang und trefflich debattieren. Doch mit den von mir vorgestellten Arbeitsweisen, ist die Unterscheidung einfach und augenfällig, glaube ich. Wie beschrieben, arbeiten wir als Softwareentwickler sowohl als Handwerker (H) wie als Ingenieure (I) und auch als Forscher (F). Arbeitsweisenverhältnisse

Norbert Eder: #fotomontag #14

Jeden Montag ein Foto. Der #fotomontag.

Graz ist eine wunderschöne Stadt, ganz besonders im Frühling. Wenn die Sonne scheint, muss man hinauf auf den Schloßberg und die Aussicht genießen.

Graz - Schloßberg

Graz – Schloßberg

Hast du eine Meinung zum Foto? Ja? Dann lass sie mich doch bitte wissen und bewerte es in den Kommentaren.

The post #fotomontag #14 appeared first on Norbert Eder.

Christina Hirth : Graph databases

My second day at the Spartakiade was dedicated to the subject of graph databases.

In computing, a graph database is a database that uses graph structures for semantic queries with nodes, edges, and properties to represent and store data. A graph database is any storage system that provides index-free adjacency. This means that every element contains a direct pointer to its adjacent elements and no index lookups are necessary. General graph databases that can store any graph are distinct from specialized graph databases such as triplestores and network databases. (source: Wikipedia)

The workshop was led by Stephan (@Piratevsninja) – thank you very much! – and we used Neo4j, the most popular open source graph database. After this day of dive-in I can say I can start to create my first graph database application without asking myself all the time what the hell am I doing :)

Also: what is a graph database?

On a very high level we can split the databases into two types: RDBMS and NoSQL. In other words: into relational and nonrelational storages.

NoSQL databases – called by Martin Fowler Not Only SQL have the main focus on the data model and not on the relations between the data. Mostly there isn’t any relation between the entities. They can be differentiated based on the data model they use. Here some examples: Key-value storages (Redis, CouchDB, etc.), Document DBs (Lotus Notes, MongoDB, etc.), Column based DBs (Cassandra, HBase, etc.).

Relational databases (RDBMS) store the data denormalized and define the relations between the data types (also ALL the entries of one type). I don’t think I have to give examples for our plain old databases: if you can join and distinct data you are in the world of relational databases.

Graph databases combine both worlds: they are relational databases with the main focus on the relations between the data (not between the data model) – or like Stephan formulated it: they put data in the context of relationships.

Nodes and relations
Emil knows Ian (source: neo4j.com)

How you define the content ?

A graph database contains nodes (instances like “Emil” and “Ian”) and relations between these nodes (“knows”). One node is defined through some properties and can be grouped through labels. They often have aliases to be easier to work with them:

Emil:Person {name:"Emil", age:"20"}, Ian:Person {name:"Ian"}

One relation is defined through a name, the nodes it connects and the direction of this connection. Relations can also have properties but they should be very carefully chosen. They must describe the relation and not the nodes.

(Emil)-[:KNOWS {certainty:100}]->(Ian)

Now is clear to see what is the difference between a “plain” relational and a graph database: for the former you care always about the data. For the latter the data means nothing without the relation to some other data.

Movies and actors

 

Fine, I can set actors in relations. So what?

The most important point is: think around a corner. The fact that I can report that Ian knows Emil and Johann knows Emil too can be interesting but I don’t think there are any new business ideas in the domain of social connections which weren’t evaluated yet. What about the information that only 20% of the Swedish tourists who visit Germany and are between 18 and 25 do not speak German? This is surely a VERY interesting to know if you sell German dictionaries in the near of Universities…
I just invented this idea – I have no idea how many Swedish guys between 18 and 25 are speaking German ;) – but this is what I mean with think around a corner!

What else remains to do?

After giving a good thought to the design: the relations and the connected data – like ids and oder characteristics but only if they are must-have – there are only a few things to do. Neo4j just like all the other graph databases have some kind of API to create, insert, update and query data. You only have to save the data across your application and create a UI (or use the one from Neo4j which is one of the coolest UI I ever saw) to create reports. Put this reports in front of the business analyst and you are done!

codefest.at [MS]: Azure Resource Explorer

Heute gibt es ein kleines Ostergeschenk für alle Developer, die mit Azure entwickeln, nämlich den ganz neuen Azure Resource Explorer.

Das Azure Resource Explorer Tool steht als Website unter https://resources.azure.com/ zur Verfügung. Damit können die Azure Management-API’s angesehen und ausprobiert werden.

Nach der Authentifizierung mit dem Azure-Login liest das Tool die damit verknüpften Providers und Subscriptions aus. Diese werden links in einem Tree aufgelistet.

Beim Anklicken eines Knoten wird das korrespondierende HTTP Kommando rechts generiert und der Output sogleich im JSON-Format darunter angezeigt – wie ein Explorer eben.

So sieht der Azure Resource Explorer aus: https://resources.azure.com

SNAGHTMLa74a3aa

Um etwa alle Azure Subscriptions auszulesen, wird dieser API Call abgesetzt:

https://management.azure.com/subscriptions?api-version=2014-04-01

SNAGHTMLa74500c

Das Tool führt also durch die Azure Management-API’s und liefert (teilweise) auch Hilfe hierzu. In den meisten Fällen folgt bei “Documentation” aber noch die Message “No documentation available”.

Es können auch neue Ressourcen direkt über Calls im Browser angelegt werden.

SNAGHTMLa795fd2

Der Sourcecode ist auf GitHub unter https://github.com/projectkudu/ARMExplorer verfügbar.

image

Eine nette, hilfreiche Spielwiese für die Azure Management-API’s!

Danke an Oliver Michalski für diesen Tipp in unserer cloudusergroup!

Ralf Westphal: Unschätzbare Arbeitsweisen

Wer über das Thema Schätzen reden will, muss zunächst eine klare Vorstellung davon haben, was denn da eigentlich geschätzt werden soll. Das ist interessanterweise aber nicht der Fall. Viel wird über Anforderungen gesprochen. Aber wenig über die Arbeit, die die Anforderungen in lauffähigen Code transformieren soll. Das scheint nicht nötig, weil es doch sonnenklar ist: das ist Codierung. Und in der

Lars Keller: 7 Jahre MVP in Folge!

Yes! Ich bin wieder Microsoft Most Valuable Professional (MVP) geworden und das nun das siebte Jahr in Folge! :-)

Sehr geehrte(r) Lars Keller,
herzlichen Glückwunsch! Wir freuen uns, Ihnen den Microsoft® MVP Award 2015 verleihen zu können! Diese Auszeichnung wird an herausragende, führende Mitglieder der technischen Communities verliehen, die ihre wertvollen praktischen Erfahrungen mit anderen Menschen teilen. Wir schätzen Ihren außerordentlich bedeutenden Beitrag in den technischen Communities zum Thema Windows Platform Development im vergangenen Jahr hoch ein.

Vielen Dank Microsoft dafür! Ich freue mich riesig ein Teil der Community zu sein. :-)

Fabian Deitelhoff: Review: Anker Bluetooth Folio Keyboard Case für iPad 2/3/4

Ich schreibe gerne. Nicht immer viel, weil die Zeit leider häufig fehlt. Und doch versuche ich das Schreiben jeden Tag aufs Neue in meinen Tagesablauf einzubauen. Bisher gelingt mir das sehr gut. Nur die Textmenge, die ich schreibe, ist von Tag zu Tag unterschiedlich. Aber das ist okay. So lange ich tatsächlich jeden Tag in die Tasten haue, bin ich damit zufrieden.

Da ich im März einige Tage lang im Urlaub war, wollte ich auch in dieser Zeit das Schreiben nicht gänzlich aufgeben beziehungsweise beiseite schieben. Natürlich würde sich die Textmenge reduzieren, aber damit habe ich nicht das Problem. Also musste ich mir überlegen, wie ich auf einer Karibik-Kreuzfahrt mit anschließenden kurzem Aufenthalt in Miami meine Schreibgewohnheit aufrechterhalten kann. Mein Ultrabook wollte ich nicht mitnehmen. Wiegt zwar nicht viel, aber das fand ich dann doch unnötig. Entschieden habe ich mich letztendlich für das iPad meiner Frau. Nur die schlechte Tastatur, da lediglich virtuell, störte mich etwas. Aber auch dafür gibt es Lösungen in Form von Tastaturen speziell fürs iPad. Beispielsweise in einem etwas dickeren Case eingearbeitet.

In diesem Beitrag möchte ich gerne das Anker Bluetooth Folio Keyboard vorstellen, das mich im Urlaub sehr gut begleitet hat und mit dem ich wirklich sehr zufrieden bin.

Verpackung & Lieferumfang

Zur Verpackung, zu sehen in Abbildung 1, gibt es nicht viel zu sagen. Abziehbare Hülle und darin die ordentlich verpackte Tastatur inklusive Zubehör in einem Karton. Alles wie es sein sollte.

Abb. 1: Verpackung der Anker Bluetooth Tastatur. Abb. 2: Zubehör zur Tastatur.

Das Zubehör fällt gering und dennoch absolut passend aus. Was ist bei einer Tastatur fürs iPad auch schon notwendig? Zwei kleine Info-Heftchen und das Ladekabel in Form eines gewöhnlichen USB-Kabels (Abbildung 2). Ein Adapter für die Steckdose fehlt allerdings.

Installation

Nach dem Auspacken ist die Tastatur sofort einsatzbereit. Der Akku ist bei dieser Größe logischerweise fest verbaut und lässt sich nicht einfach tauschen. Aufgeladen ist er schon und so muss das iPad nur im Querformat in die oberen Halterungen des Schutzhülle eingerastet werden. Dazu ist etwas Druck notwendig. Allerdings nicht übermäßig. Lediglich die Halterungen ganz leicht zu Seite drücken. Ist das iPad eingerastet, kann es praktisch sofort losgehen.

Die Installation beschränkt sich auf das Koppeln von Tastatur und iPad über Bluetooth. Einfach das iPad aufstellen und die untere Hälfte nach vorne in Richtung Tastatur bewegen, da sich dort der Magnetstreifen befindet, der das iPad auch gleich im korrekten Winkel hält. Beim Einrasten blinkt die grüne LED auf der rechten Seite kurz auf. Da der Pairing-Modus der Bluetooth-Verbindung im Auslieferungszustand der Tastatur nicht aktiv ist, einfach über die Tastenkombination Fn + Bluetooth-Taste aktivieren und anschließend Bluetooth auf dem iPad aktivieren, falls das nicht eh schon der Fall ist. Jetzt muss die Tastatur nur noch in den Verbindungseinstellungen des iPads ausgewählt und angeklickt werden. Die Tastatur meldet sich mit dem Namen Anker TC941, wie Abbildung 3 auch zeigt. Abschließend nur noch den Code über die Tastatur eingeben, der am iPad angezeigt wird und beide Geräte sind miteinander verbunden.

Abb. 3: Die Bluetooth Tastatur in der Übersicht der Bluetooth Geräte.

Abb. 3: Die Bluetooth Tastatur in der Übersicht der Bluetooth Geräte.

Die oben beschriebene Installation ist in der Regel in unter einer Minute erledigt. Also nichts wildes und zudem sehr komfortabel. Außerdem muss der Vorgang nur einmal pro iPad durchgeführt werden. Ab jetzt reicht es aus, das iPad mit den Magnetstreifen zu verbinden und die Verbindung wird automatisch herstellt. Vorausgesetzt natürlich, die Bluetooth-Verbindung auf dem iPad ist weiterhin aktiv.

Einsatz

Wurde die Tastatur mit dem iPad gekoppelt, kann es auch direkt losgehen. Sofort können die Sondertasten zur Steuerung des iPads genutzt werden. Auch das Schreiben in einem beliebigen Textprogramm ist natürlich möglich. Ich habe während des Urlaubs hauptsächlich Google Chrome, Microsoft OneNote und Microsoft Word genutzt. Alles ohne jegliche Probleme.

Ich empfand das Schreibverhalten als sehr angenehm und absolut positiv und war überrascht, wie schnell ich auf der, im Vergleich zu einer normalen Desktop-Tastatur, kleineren Tastatur tippen konnte. Sehr schönes Schreibverhalten und nicht besonders laut. Flüsterleise, wie in vielen Rezensionen häufig zu lesen ist, finde ich die Tastatur zwar nicht, laut sind die Anschläge aber auch nicht. Ist der Raum nicht gänzlich still, sind keinerlei Schreibgeräusche zu hören. Die Tasten und der Tastendruck fühlen sich durchweg gut und reaktiv an. Den Anschlag an sich empfinde ich als ausgezeichnet. Auch was die Darstellung des entsprechenden Zeichens auf dem iPad-Bildschirm anbelangt. Eine Verzögerung ist beim Schreiben praktisch nicht wahrzunehmen. Bis auf Sondertasten, die eine spezielle Funktion vom iPad ansteuern. Zu den Funktionen im nächsten Abschnitt aber mehr.

Manchmal wurde ein Zeichen mehrfach ausgeführt. Häufig direkt nach dem Koppeln. Ich schätze, dass die Bluetooth-Verbindung noch nicht ganz stabil war. Vielleicht war auch das iPad mit etwas im Hintergrund beschäftigt. Dieses Problem war wie ein Lag, trat allerdings während des gesamten Urlaubs nur drei Mal auf, weswegen ich auch überhaupt keine Zeit mit einer Fehlersuche oder Recherche verbracht habe.

Beim 10-Finger-Schreiben musste ich mich natürlich erst etwas umgewöhnen. Die Tasten sind kleiner als auf einer regulären Desktop-Tastatur, was der Größe der iPad-Hülle geschuldet ist. Diese Eingewöhnungsphase hat allerdings maximal 30 Minuten in Anspruch genommen. Danach konnte ich sehr flüssig auf der Tastatur schreiben.

Deutlich erhöht war der Stromverbrauch. Bei aktivem Schreiben, mit einigen Lesepausen zwischendurch, habe ich circa 10% des iPad-Akkus in einer Stunde verbraucht. Das finde ich schon deutlich mehr, als das iPad für sich genommen verbrauchen würde. Das iPad war in der Zeit nicht mit dem WLAN verbunden (deaktiviert) und besitzt kein GSM-Modul. Ob dieser Stromverbrauch tatsächlich von der Bluetooth-Verbindung herrührt oder sonst etwas dafür (mit-)verantwortlich war, lässt sich im Nachhinein schwer bis gar nicht beantworten. Gestört hat es mich trotzdem nicht. 10 Stunden sind auch so kein Problem, waren im Urlaub allerdings auch überhaupt kein Thema. In der Regel kann das iPad am Abend geladen werden.

Funktionen

Bei der Tastatur handelt es sich um ein normales QWERTZ-Layout. Zumindest habe ich mich dafür entschieden. Der Hersteller Anker bietet auch andere Layouts an. Neben den Standardtasten für Buchstaben, Zahlen und Sonderzeichen, sind auch weitere Steuerzeichen wie Tab, Shift, Caps Lock, Ctrl, Alt und Cmd vorhanden. Tab funktioniert beispielsweise in Microsoft OneNote ohne Probleme. Andere Tastenkombinationen, wie beispielsweise Shift + Tab, um den Einzug wieder zu verringern, werden anscheinend aber nicht unterstützt oder emuliert.

Daneben sind auch einige Sondertasten vorhanden, mit denen das iPad direkt gesteuert werden kann. Beispielsweise für die Home-Taste, den Lock-Screen, die Helligkeit des Displays, die virtuelle Tastatur und zur Steuerung der Audio-Wiedergabe. Damit lässt sich zum Beispiel zwischen Apps hin und her schalten, da auch das doppelte Drücken der Home-Taste funktioniert. Das gilt auch für Siri oder für das Ausschalten des iPads über die Tastatur.

Andere Sondertasten, wie die Funktionstasten F1 bis F12 fehlen dagegen, was auch nicht verwunderlich ist, da die Tastatur für ein iPad konzipiert wurde. Ich erwähne es an dieser Stelle nur der Vollständigkeit halber. Abbildung 4 zeigt eine Aufnahme der Tastatur von oben.

Abb. 4: Aufnahme der Tastatur von oben.

Abb. 4: Aufnahme der Tastatur von oben.

Zusätzlich bietet die Anker Bluetooth Folio Tastatur noch einen Schlafmodus mit automatischer Sleep- und Wake-Funktion und eine lange Batterielaufzeit. Letztere beträgt laut Hersteller mehr als vier Monate. Erst dann muss der interne Akku über ein mitgeliefertes Ladekabel wieder mit Energie versorgt werden. Der Schlafmodus sorgt dafür, dass sich die Tastatur in einen Ruhemodus versetzt, wenn sie zehn Minuten oder länger nicht genutzt wurde. Danach verbindet sie sich aber wieder automatisch, wenn sie genutzt wird. Ähnlich verhält sich das mit dem iPad, bei dem nach einiger Zeit der Bildschirm deaktiviert wird. Hier reicht ein Tastendruck zum Aufwecken auf. Die Bluetooth-Verbindung wird hier allerdings aufrechterhalten. Dieses Aufwecken beziehungsweise das erneute Verbinden geschieht in 1-2 Sekunden. Diese Verzögerung fällt kaum auf und ist daher nicht der Rede wert.

Fazit & Bewertung

Das Anker Bluetooth Folio Keyboard ist meine erste Bluetooth-Tastatur für das iPad, dessen Kauf sich auch gleich beim ersten Einsatz gelohnt hat. Ich bin sowohl von den technischen Funktionen als auch vom Schreibgefühl her absolut zufrieden mit der Tastatur. Letzteres ist natürlich ein weiches Kriterium, das für mich jetzt bei dieser Tastatur gepasst hat. Ob beispielsweise der Anschlag und damit auch das Schreibgefühl in Ordnung sind, muss allerdings jeder für sich selber austestet.

Dass der Akku des iPads jetzt nicht mehr so lange hält wie ohne Tastatur, ist mir zwar aufgefallen, allerdings auch nicht sonderlich negativ. An die so verringerte, maximale Nutzungsdauer des iPads bin ich im Urlaub auf keinen Fall ran gekommen. Wer längere Sessions plant, muss das eventuell berücksichtigen. Allerdings lohnt sich auch irgendwann wieder ein richtiger Laptop oder ähnliches, wenn wirklich viel gearbeitet werden soll.

Alles in allem bin ich sehr zufrieden mit der Anker Bluetooth Tastatur und kann sie jedem absolut empfehlen, der eine günstige Tastatur für sein iPad sucht.

Sven Hubert: There is no rose without a thorn: Using the TFS Task Board to maintain remaining work disregards completed work–learn how to handle it

The TFS Task Board that is accessible by Web Access is a common and comfortable tool to update task status. A lot of our customers use it e.g. in daily meetings to show what they have achieved and what to do next. Since the Remaining Work field is visible in the task board as shown in the following screenshot, its value can be updated on the task board directly.

image

On the downside, another important field is ignored in that case: Completed work.

 

This is an out-of-the-box field of the following Process Templates:

  • MSF for Agile Software Development
  • MSF for CMMI Process Improvement

Typically the result is that completed work remains on the original value, which usually is empty or zero.

In the happy day scenario we can assume that a settled team “burns” the time that they have spent spent on a task. Based on that hypothesis, the following algorithm can help.

Happy day scenario:

If a user reduces Remaining Work but leaves the field Completed Work untouched, the difference of Remaining Work shall be added to Completed Work field. E.g. Remaining Work = 10, Completed Work = 4; user changes Remaining Work from 10 to 6 and does not modify Completed Work; we assume that the difference (4) can be added to Completed Work –> Completed Work = 4 + 4 = 8

image

Normally, the fields Remaining Work and Completed Work have the following values after updating Remaining Work as shown in the screenshot above:

image

Under the previously outlined circumstances we actually want to have the following values:

image

In other cases:

Certainly there are tasks that are not that easy to estimate. Even experienced developers might have some blocking points that counteract their estimation. In those cases the user might manually open the Task work item to manually set values for Remaining Work and Completed Work.

Solution

We have automated the manual activity of setting Completed Work in the happy day scenario using a server-side background service. This feature is available in TFS ASAP Online, the Automation Service and Automation Platform for Visual Studio Online. It is available as an official extension for Visual Studio Online as shown in the following screenshot.

image

However, there are scenarios that do not correspond to the hypothesis explained before. Especially if the accuracy of estimate is too low, the manual work for setting Remaining Work and Completed Work tends to be the happy day scenario.

All others might be happy with TFS ASAP Online, taking care of calculating Completed Work field in the happy day scenario. Hence, in most cases, the developer only has to maintain Remaining Work without any further manual effort. This reduces manual work and avoids mistakes and inconsistencies. Feel free to register for TFS ASAP Online. In case of any questions, don’t hesitate to ask via tfsasaponline@aitgmbh.de.

This feature will also be available in TFS ASAP  for on premise installation soon.

There is no rose without a thorn: Using the TFS Task Board to maintain remaining work disregards completed work–learn how to handle it is a post from: AIT Blog

Christian Binder [MS]: Stellen Angebot – SelectLine sucht Entwickler für Team Foundation Server (TFS)

Stellen Angebot -  Die Firma SelectLine sucht einen Entwickler für Team Foundation Server. Hier der Link zu Stellenauschreibung. Wer Interesse hat, kann sich direkt per E-Mail an: bewerbung@selectline.de für weitere Informationen wenden.

Christian Binder [MS]: Die Zukunft von Team Foundation Server Version Control

TFS unterstützt bekanntlich zwei Versions Control Systeme. Team Foundation Server Version Control als CVCS und Git als DVCS. In diesem Zusammenhang kommt immer wieder die Frage auf, ob TFVC nicht mehr weiterentwickelt wird. Die Antwort ist ein klares Nein. Brain Harry (CVP) hat dazu einen entsprechenden Post veröffentlicht, der hier Transparenz schafft und entsprechende falsche Gerüchte entkräften sollte. Die Kunden haben die Wahl, ob Sie CVCS Workflows oder DVCS Worklflows für Ihre Entwicklung nutzen möchten.

Chris

Marco Scheel: Links for 2015-04-01 [del.icio.us]

codefest.at [MS]: So lässt sich die Cloud auch für ihre Organisation nutzen

Nicht dass mir die Themen im Bereich der Softwareentwicklung im Zeitalter von Cloud ausgehen oder mich weniger interessieren würden – ganz im Gegenteil. Aber ich denke dass es auch für uns Entwickler immer wichtiger wird, einen guten Überblick über die sogenannten Infrastruktur Themen zu bekommen.
Und dafür haben die Kollegen vom “IT Pro Blog” eine sehr interessante Blog Serie ins Leben gerufen…

Holger Schwichtenberg: MS-DOS Mobile

Das neue Mobilbetriebssystem MS-DOS Mobile ist klein, schwarz und leistungsstark. Und zur Abwechslung stehen zur Bedienung einmal keine Icons oder Kacheln im Vordergrund: Die Kommandozeile soll beim Aufruf der vorinstallierten Anwendungen behilflich sein.

codefest.at [MS]: Microsoft Unity Camp und GameCraft

Wir haben wieder zwei spannende Events im Mai für euch, die in Richtung Spiele-Entwicklung gehen.

image

Am Freitag, 15. Mai 2015 findet das Microsoft Unity Event statt. Wir werden hier einen Technischen Evangelisten von Unity dabei haben, der euch Unity 5 vorstellen wird. Danach gehts weiter mit dem Hands-On Workshop Teil. Es wird zwei Tracks geben:

  • Unity Workshop: Hier entwickelt ihr ein erstes 2D Spiel. Dieser Track ist auch für Einsteiger in Unity bzw Spiele-Entwicklung geeignet. 
    Voraussetzung: eigener Rechner mit Unity3D
  • Unity Porting Lab: In diesem Track zeigen wir, wie ihr ein Unity Spiel als Windows Store/Windows Phone App portiert. Bitte nehmt hierfür ein Unity Spiel mit, dass ihr schon entwickelt habt. Wir geben euch Tipps und Unterstützung, damit ihr am Ende des Workshops euer Spiel für die Windows App Stores portiert habt.
    Voraussetzung: eigener Windows 8.1 Rechner, Visual Studio, fertiges Unity Spiel

Für beide Tracks gibt es einen Teilnahmebeschränkung von 30 Teilnehmern. Ihr könnt auch ab sofort hier anmelden.

 

image

Am Samstag, 16. Mai 2015 holen wir die irische GameCraft für euch nach Wien. Die Game Craft ist ein eintägiger Game Jam, der in Irland gegründet ist. Im Prinzip ist es ein Hackathon, wo ihr das am Vortag Erlernte gleich anwenden könnt und eure eigene Ideen umsetzen könnt. Wenn ihr eure Skills (sei es Development, Game Story, Art Assets, etc) an einem Spiel anwenden wollt, seid ihr hier richtig. Das Thema für das Event werdet ihr an dem Tag erfahren.

Für die GameCraft könnt ihr euch hier anmelden.

Wir freuen uns auf ein spannendes Wochenende mit euch!

Karsten Kempe: Visual Studio Enterprise Edition

VisualStudioLogoUnd es gibt ihn doch – den Osterhasen. Und er trägt ein Visual Studio Branding! Gestern wurde bekannt, dass Microsoft zur Einführung der neuen Visual Studio Version eine neue Edition einführen wird. Visual Studio Enterprise wird die Features von Visual Studio Premium und Visual Studio Ultimate vereinen. Damit macht Microsoft vielen Entwicklern, die schon lange auf Ultimate-Features zu erschwinglichen Preisen gewartet haben, ein großes Ostergeschenk.

Mit Visual Studio 2015 baut Microsoft seine Produktpalette um und vereinfacht das Editionsmodell. Es wird drei Visual Studio Editionen geben: Visual Studio Community, Visual Studio Professional und Visual Studio Enterprise.

VS2015_Editions

Interessant ist ebenfalls die Bekanntgabe, dass alle Kunden von „Visual Studio Premium mit MSDN“ automatisch zu „Visual Studio Enterprise mit MSDN“-Kunden hochgestuft werden. Alle “Visual Studio Professional”-Nutzer haben in den nächsten Wochen die Möglichkeit, „Visual Studio Premium mit MSDN“ zu einem rabattierten Preis zu erwerben und würden dann ebenfalls von einem kostenlosen Upgrade auf Visual Studio Enterprise profitieren. Die genauen Bedingungen könnt ihr hier nachlesen oder bei Eurem Lizenz-Partner erfahren.

[1] https://www.visualstudio.com/vs-2015-product-editions#offer
[2] http://blogs.msdn.com/b/visualstudio/archive/2015/03/31/announcing-the-visual-studio-2015-product-line.aspx

 

Norbert Eder: Neues Familienmitglied: Sony Alpha 6000

Seit gestern habe ich vermutlich den Ersatz für meine Canon EOS M Hause:

Sony Alpha 6000

Sony Alpha 6000

In den nächsten Tagen und Wochen werde ich wohl ausreichend testen und sehen, ob die Kamera wirklich das erfüllen kann, wofür ich sie mir angeschafft habe. Mehr dazu später. Vorerst habe ich ein paar hilfreiche Links für jeden der mit einer Sony ILCE startet:

Fotos werden folgen!

The post Neues Familienmitglied: Sony Alpha 6000 appeared first on Norbert Eder.

Holger Schwichtenberg: Einblicke in die Planung für Visual Studio

Microsoft hat erstmals eine "Feature Timeline" für die Entwicklungsumgebung Visual Studio veröffentlicht. Diese enthält Ankündigungen für Features, die in Visual Studio 2015 und später erscheinen werden

Marco Scheel: Links for 2015-03-30 [del.icio.us]

Code-Inside Blog: JSON.NET deserialize to abstract class or interface

Base Class & Implementations

public abstract class BaseFoo
{
    public string FooBarBuzz { get; set; }
}

public class AFoo : BaseFoo
{
    public string A { get; set; }
}

public class BFoo : BaseFoo
{
    public string B { get; set; }
}

When we deserilize it we need somehow a “marker”-property and I use the “FooBarBuzz” property from the BaseFoo-class as my marker. If it contains “A”, then it is implementation “AFoo” and “B” for “BFoo”.

Serialize

The serialization part works as expected:

AFoo a = new AFoo();
a.FooBarBuzz = "A";
a.A = "Hello World";

BFoo b = new BFoo();
b.FooBarBuzz = "B";
b.B = "Hello World";

List<BaseFoo> allFoos = new List<BaseFoo>();
allFoos.Add(a);
allFoos.Add(b);

var result = JsonConvert.SerializeObject(allFoos);

Resulting Json:

x

Deserialize and boom…

If we continue now and just use the typical code we get a nice exception:

var test = JsonConvert.DeserializeObject<List<BaseFoo>>(result);

Exception:

Additional information: Could not create an instance of type ConsoleApplication6.BaseFoo. Type is an interface or abstract class and cannot be instantiated. Path ‘[0].A’, line 1, position 6.

Introducing a simple JsonConverter

The exception is pretty clear, because JSON.NET has no knowledge about our convention. The way to go* is to write a JsonConverter. I found a couple of implementations on StackOverflow, but this one seems to be the easiest and best option.

* Small Update based on the comment from Michael: JSON.NET can also include the TypeName in the JSON as a “$type” property. If this is not an issue for you, then just add the “TypeNameHandling.Auto” to the JsonSerializerSettings and it will work. In my actual scenario I want a clean JSON output, without JSON.NET magic. That’s the reason for the converter.

public class FooConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(BaseFoo));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject jo = JObject.Load(reader);
        if (jo["FooBarBuzz"].Value<string>() == "A")
            return jo.ToObject<AFoo>(serializer);

        if (jo["FooBarBuzz"].Value<string>() == "B")
            return jo.ToObject<BFoo>(serializer);

        return null;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

When we read the JSON we look for our “FooBarBuzz”-property and serialize it to the correct implementation.

Let’s use our new JsonConverter

Just create a new instance of the Converter and apply it to the DeserializeObject method and you are done.

JsonConverter[] converters = { new FooConverter()};
var test = JsonConvert.DeserializeObject<List<BaseFoo>>(result, new JsonSerializerSettings() { Converters = converters });

Easy, right?

The full sample can be viewed on GitHub

Karsten Kempe: Who broke the build – Teil II

VS_BuildManagementIm ersten Teil der Serie “Who broke the Build” habe ich beschrieben, was mich dazu bewogen hat ein Tool zu entwickeln, welches die Ergebnisse eines Nightly-Builds visualisiert und per Mail an alle Entwickler verschickt. In Teil zwei werde ich Euch erklären, wie genau die Applikation funktioniert und Euch ein paar ausgewählte Code Snippets dazu zeigen.

Der Build Notification Service

Im Kern ist der Build Notification Service eine .NET Konsolenapplikation, welche die TFS-Client API verwendet, um eine Verbindung zum Team Foundation Server herzustellen. Der Service verwendet das TFS-Client-Object-Model, um auf die Build Information eines TFS Team Projekts zugreifen zu können. Der Dienst liest alle beendeten Build Definitionen der letzten 24 Stunden aus und verschickt deren Ergebnis als Email im html-Format über die Exchange Web Services an alle Mitglieder einer Mailing-Liste.

Who broke the build - Mailing List

Eine Verbindung zum TFS aufbauen

Um die gewünschten Informationen des TFS Build-Systems zu erhalten, muss der „Build Service“ des Team Foundation Servers angefragt werden. Um diesen Dienst anzusprechen wird eine Instanz der TFSTeamProjectCollection Klasse benötigt, welche die GetService(Type)-Methode implementiert, über die wiederum eine Instanz von IBuildServer geladen werden kann.

// Lade Konfigurations- und Verbindungsinformationen
Config config = LoadConfigInformation();
Uri uri = new Uri(config.Url);
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(uri);
IBuildServer buildService = tfs.GetService(typeof(IBuildServer)) as IBuildServer;

Alle notwendigen Parameter, wie z.B. die Collection-Url oder der Team Projekt Name, werden aus einer Konfigurationsdatei ausgelesen und als die entsprechenden Parameter übergeben.

Build Details abfragen

Wenn der „Build Service“ des Team Foundation Server erfolgreich geladen werden konnte, lässt sich mit Hilfe einer Build Detail Spezifikation IBuildDetailSpec die Auswahl der zu ladenden Build-Ergebnisse einschränken. In der Build Detail Spezifikation wird beispielsweise angegeben in welchem Team Projekt Build Definitionen gesucht, wie viele Builds pro Definition abgefragt und wie das erwartete Ergebnis sortiert werden soll.

Besonders wichtig an dieser Stelle ist der Parameter InformationTypes der Build Detail Spezifikation. Durch diesen Parameter kann die Informationstiefe der Abfrage gesteuert werden, um nicht benötigte Information im Vorfeld auszufiltern und somit die Antwortzeit zu reduzieren. Durch das explizite Setzen von NULL, werden weder assoziierte Work Items, noch assoziierte Changesets oder Error Details über den Build Service ausgelesen, wodurch die Response-Zeit der QueryBuilds-Methode drastisch reduziert wird.

// Erstelle IBuildDetailSpec, um die Antwort der Build-Abfrage einzuschränken
// Maximal einen Build per Definition
// Sortiert nach FinishTime
// Keine zusätzlichen Informationen laden (z.B. Error Details, etc.)
// Nur Builds aus den letzten 24 Stunden
 
IBuildDetailSpec buildDetailSpec = buildService.CreateBuildDetailSpec(config.TeamProject"*");
 
buildDetailSpec.MaxBuildsPerDefinition = 1;
buildDetailSpec.QueryOrder = BuildQueryOrder.FinishTimeDescending;
buildDetailSpec.InformationTypes = null;
buildDetailSpec.MinFinishTime = DateTime.Now.AddHours(-24.0);
 
var htmlBody = string.Empty;
var buildQueryResult = buildService.QueryBuilds(buildDetailSpec);

Verarbeiten der Build Informationen

Die Ergebnisse der Abfrage werden im Array buildQueryResult.Builds vom Typ IBuildDetail hinterlegt und werden zur weiteren Verwendung der Reihe nach ausgewertet und in ein Html-Template eingefügt. Die zum Einsatz kommende Html-Vorlage ist vergleichsweise primitiv und sieht wie folgt aus:

<b>{1}</b> Start Time: End Time: <a href=”{4}”>Details…</a>   {2} {3}
<table width=”400″>
<tbody>
<tr>
<td width=”60″>
<img alt=”" src=”{0}” width=”50″ height=”50″ />
</td>
</tr>
</tbody>
</table>

Jeder einzelne Platzhalter wird durch einen Wert aus dem Array der Build-Ergebnisse ersetzt. Diese Prozedur wird so oft durchlaufen, wie es abgeschlossene Build Definitionen im Array gibt. Wenn alle Teil-Html-Vorlagen ausgefüllt sind, werden sie in eine große Html-Vorlage zusammengefügt und anschließend als Email verschickt.

Verwenden der Exchange Web Services

Die Emails des Build Notification Service werden über die managed API der Exchange Web Services (EWS) verschickt. Die EWS bieten dafür ein relativ einfaches Objektmodell, um Nachrichten zu verschicken. Für detaillierte Informationen zu den Exchange Web Services empfiehlt es sich den Bereich „Get started with the EWS Managed API“ der MSDN genauer zu studieren.

Bevor eine erste Email versendet werden kann, muss der Exchange Service instanziiert und die entsprechenden Credentials zur Authentifizierung gesetzt werden. In diesem Beispiel kommen die Default Credentials zum Einsatz, da die Applikation innerhalb der Domain ausgeführt wird und die Nachrichten über einen on-premise Exchange Server verschickt werden.

// Initialisiere den ExchangeService und setze Default Credentials
ExchangeService eService = new ExchangeService();
eService.UseDefaultCredentials = true;

Als letzten Schritt der Initialisierung muss noch die Service URL gesetzt werden. Dafür wird in diesem Fall der AutodiscoverService geladen, um die Benutzereinstellungen des aktuellen AD-Users zu laden. Aus dessen Response kann dann eine valide URL entnommen werden, die vom EWS verwendet werden kann.

// Lade Autodiscover Service der Exchange Web Services und lade User-Einstellungen
AutodiscoverService autodiscoverService = new AutodiscoverService();
GetUserSettingsResponse response = autodiscoverService.GetUserSettings(smtpAdresse,
UserSettingName.InternalEwsUrl);
eService.Url = new Uri((string)response.Settings[UserSettingName.InternalEwsUrl]);

Der Rest ist dann straight-forward. Die Instanz des EWS wird in eine EmailMessage induziert und mit den entsprechenden Informationen angereichert. Als Email Body wird die Html-Vorlage mit allen Build Definitionen verwendet und die Empfänger werden aus der Konfiguration gelesen und angehängt.

Der Trick mit den Status Bildern

Damit der Status eines Builds durch ein Image in der Email visualisiert werden kann, wird der Status-Platzhalter aus der Html-Vorlage nur mit einer Content-Id befüllt (z.B. cid:picOK). Diese Content-ID wird kurz vor dem Verschicken der Email mit einem Mail-Attachement verknüpft, welches die gleiche Content-ID bekommt. Dadurch wird der Text aus der Html-Vorlage durch das Attachement ausgetauscht und ein Status-Bild angezeigt.

Wiederkehrender morgendlicher Task

Wie eingangs angesprochen soll den Entwicklern ein Feedback über die Build Läufe der letzten Nacht gegeben werden. Da der Build Notification Service eine Client Anwendung ist und das TFS Client Object Modell verwendet, muss die Anwendung auf einem Rechner ausgeführt werden auf dem Visual Studio installiert ist. Am einfachsten ist es einen täglichen Task im Task Scheduler anzulegen und so das Konsolenprogramm zu starten.

Transparenz belebt das Geschäft

Damit sind die Grundlagen geschaffen und es kann täglich eine Mail generiert werden, die den Status aller relevanten Nightly Builds visualisiert und an alle Entwickler verschickt. Somit verfügt jeder über den gleichen Informationsstand. Aber Mails sind geduldig und können ignoriert, verschoben oder gelöscht werden. Somit ist die Mail nur so gut wie jedes andere Informationsmedium auch – Team-Mitglieder, die sich schon immer gekümmert haben, freuen sich über die Übersicht. Die Anderen können sich nach wie vor ihre Verantwortung drücken.

Auf der Manage Agile 2013 Konferenz in Berlin hielt Uwe Henker den Vortrag „Human Factors and SCRUM“. Herr Henker beschrieb in seinem Vortrag wie Transparenz und die Visualisierung von Ergebnissen eine Verbesserung im „Gesamtsystem“ herbeiführen können. Aufbauend auf dieser These wurde der Logarithmus des Build Notification Service weiterentwickelt, um den Prozess noch transparenter zu machen. Der Dienst soll nun zusätzlich aus einem fehlgeschlagenen Build das potentiell verantwortliche Entwicklungsteam bestimmen und diese Information über die tägliche Status-Mail
verbreiten. Dabei geht es weniger darum einen Schuldigen zu finden, sondern um eine erste Anlaufstelle für die Fehlersuche zu nennen. Es soll ein erster Kümmerer gefunden werden, der auch die Lage beurteilen kann – da der Fehler schließlich irgendwo in dessen Code aufgetreten ist.

Implementieren lässt sich das relativ einfach. Der „Build Service“ muss lediglich für eine bestimmte Build Definition die Build Details abrufen.

// lade Liste der Verantwortlichen aus den verschiedenen Bereichen
// lade zusätzlichen Informationen für konkrete Build Definition
// prüfe den Build Status und suche Verwantwortlichen
IDictionary&lt;string, string&gt; map = LoadResponsibles();
IBuildDetail buildDetail = buildService.GetAllBuildDetails(buildDefinition.Uri);
if(buildDetail.Status == BuildStatus.Failed)
{
WhoBrokeTheBuild(buildDetail, tfs, map);
}

Nachdem Laden der Build Details wird der Status des Build überprüft. Im „Nicht-Gut“-Fall wird dann nach einem Kümmerer aus der Liste der möglichen Verantwortlichen gesucht. Dazu werden in der WhoBrokeTheBuild()-Methode die Build Errors der Build Definition abgefragt und ausgewertet.

// Build Errors über InformationNodeConverters laden
List errors = InformationNodeConverters.GetBuildErrors(buildDetail);
foreach (IBuildError err in builderrors)
{
// do something
// search for responsible in map
}

Der Name des Kümmerers bzw. des Teams wird nun solange gezeigt, bis der Fehler bereinigt wurde oder durch einen neuen Kümmerer (neuer Fehlerfall) ersetzt wird.

Fazit

Einige Wochen nach der Einführung der Build Status Email bleibt festzustellen, dass diese neue Transparenz zu etwas höherer Qualität geführt hat. Die Builds laufen stabiler und auftretende Fehler, werden schneller bereinigt. Allerdings ist auch festzustellen, dass sobald der Logarithmus keinen Kümmerer ausfindig machen kann, sich auch kein Verantwortlicher freiwillig meldet – und sich dadurch die Fehlerbehebung wieder verzögert.

Was also bleibt? Zum einen die Erkenntnis, dass der Algorithmus noch wesentlich besser werden muss und das die Qualität einer Software immer nur so hoch ist wie die Motivation seiner Entwickler.

Mögliche Sinnvolle Erweiterung

Zugegebenermaßen ist der Build Notification Service ein wenig „dumm“, da er im Moment nur ein einziges Team Projekt überwacht und auch nicht zwischen Teams unterscheidet. D.h. eine Fokussierung und Kanalisierung der Information ist im Moment nicht möglich. Deswegen wäre eine sinnvolle Erweiterung für die Zukunft, die Überwachung von Teams und Team Projekten konfigurierbar zu machen.

Eine weitere Erweiterung könnte die Abschaffung der klassischen Mailing-Liste sein, die jetzt in der Konfigurationsdatei hinterlegt werden muss. Wenn man den Team-Gedanken aus der ersten Erweiterung aufgreift, könnte es sich durchaus lohnen einen Mechanismus zu schreiben, der die Mitglieder aus den jeweiligen Teams ausliest, deren Mail-Adresse bestimmt und ihnen die teamrelevanten Build-Informationen zuschickt.

Weitere Ideen oder Anregungen könnt Ihr gerne im Kommentar hinterlassen. Ich würde mich freuen.

[1] dotnetpro 02/14 Andy Grothe – Sie haben Post

[2] http://msdn.microsoft.com/de-de/magazine/jj553516.aspx

[3] http://msdn.microsoft.com/en-us/library/office/jj220499(v=exchg.80).aspx

[4] http://msdn.microsoft.com/de-de/library/bb130146.aspx

 

Norbert Eder: #fotomontag #13

Jeden Montag ein Foto. Der #fotomontag.

Ich habe eine neue Leidenschaft entdeckt. Die S/W-Fotografie. “Ja, das musste doch kommen” werden sich so manche denken. Vielleicht muss das auch Teil der Entwicklung sein.

Das nachfolgende Foto ist aus einer Spielerei entstanden und anfangs dachte ich mir dabei auch nicht viel. In Lightroom erwischte ich mich dann als ich einige Minuten auf das Foto starrte und gedanklich in die Ferne (eigentlich in die Höhe) glitt. Für mich ist das ein richtiges Nachdenkbild, oder etwa nicht?

Die Wolkenlampe

Die Wolkenlampe

Hast du eine Meinung zum Foto? Ja? Dann lass sie mich doch bitte wissen und bewerte es in den Kommentaren.

The post #fotomontag #13 appeared first on Norbert Eder.

friends header

bloggers headline

links header

 
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.