codefest.at [MS]: Automation von Azure-Teil 1

Auf der Build Conference 2014 wurden mehr als 160 Sessions gehalten. Aus der Fülle an Themen habe ich mir Automatisierung in Microsoft Azure herausgepickt, da ich die neuen Methoden zur Prozessautomatisierung sehr spannend und hilfreich finde.

Warum finde ich das Thema Automatisierung so wichtig? Nun, oft deployt man als Developer ein und dasselbe Projekt in verschiedene Azure-Umgebungen oder n-Mal in verschiedene Subscriptions, etwa als Stage oder als Production-System oder etwa für die Umsetzung von SaaS Multi-Tenant Lösungen. Hierfür braucht es sinnvollerweise eine Unterstützung um diese Tasks zu automatisieren. Microsoft stellt hierzu neuerdings mehrere Möglichkeiten bereit.

Zum Thema Azure-Automatisierung haben zwei Sessions auf der Build stattgefunden – sehr fein, dass alle Vorträge auf Channel9 online abrufbar (und downloadable) sind.

Ich habe die erste Session von Brady und Joe durchgearbeitet und möchte meine Erkenntnisse hier zusammenfassen und teilen:

Varianten der Automation

Es gibt nun mehrere Möglichkeiten zur Automatisierung, Microsoft nennt diese “The Microsoft Azure Service Management Stack”. Die Folie zeigt diese Varianten im Überblick.

image

Das Slide zeigt die grundsätzliche Architektur der neuen Azure Automation:

  • Als Basis stellt Microsoft eine Reihe von NuGet Packages bereit und nennt diese “SDK Common”.
  • Darauf bauen die Microsoft Azure Management Libraries for .NET auf. Weiter Libraries gibt es auch für Node.js und Java. Für das Erstellen der Libraries in verschiedenen Sprachen verwendet Microsoft intern ein eigenes Code Generator Tool, das bald als Open Source bereitstehen wird.
  • Auf den Libraries setzten die neuen PowerShell Cmdlets auf. Damit können Azure Ressourcen administriert werden.
  • Hierauf stehen Automation Services bereit, etwa Runbooks, das sind PowerShell Workflows.

Azure Management Libraries

Automatisierung von Azure gab es auch zuvor, jedoch nur recht mühsam über REST-Schnittstellen, siehe Service Management REST API Reference. Die Management Libraries vereinfachen die gesamte Kommunikation mit den Services erheblich. Sie sind komplett async gebaut, darauf gibt es allerdings auch Wrapper für sync-Support – als Developer kann man sich so die Methode aussuchen.

Um die Management Libraries zu verwenden, werden die erforderlichen Pakete via NuGet installiert. Microsoft wird diese Pakete eventuell noch umbenennen, derzeit heißen sie Microsoft.WindowsAzure.*.

image

Um alle Bibliotheken gesammelt zu installieren (diese basieren auf Microsoft.WindowsAzure.Common 1.0.1, siehe unten) wird das Gesamtpaket über die NuGet Console bezogen:

Install-Package Microsoft.WindowsAzure.Management.Libraries

-pre wie in den Slides ist nicht mehr erforderlich. Alternativ können einzelne Pakete installiert werden, wie in obigem Beispiel etwa nur WebSites oder Storage, etc. Aufmerksame Leser werden gesehen haben, dass derzeit noch Mobile Services fehlen, ServiceBus ist dzt. noch Beta – diese sollen bald folgen.

Auf NuGet findet ihr alle aktuellen Pakete: http://www.nuget.org/packages?q=azure.management
(Diese sind dort bereits von windowsazure auf microsoftazure umbenannt… und werden standardmäßig nach den letzten Installs sortiert.)

image

Das Azure Management SDK (ab NET Framework 4.5, 4.5.1) steht auch als Open Source auf GitHub bereit:
https://github.com/Azure/azure-sdk-for-net

Seit 9. April sind die Azure Management Libraries for .NET v1.0 offiziell verfügbar, siehe Brady Gaster´s Blog: Announcing the General Availability of the Microsoft Azure Management Libraries for .NET und in NuGet Windows Azure Common Library (ganz aktuell ist v.1.0.2 vom 17. April):

Install-Package Microsoft.WindowsAzure.Common

Über den NuGet Manager wird die gesamte Bibliothek (Version vom 17. April) über die Suche nach “microsoft.windowsazure.management” gestartet und das Paket installiert.

image

Damit kommen eine ganze Reihe Microsoft.WindowsAzure.* Bibliotheken ins Projekt.

Weitere Infos darüber gibt es in Jeff Wilcox´ Artikel Introducing the Microsoft Azure Management Libraries.

Authentifizierung an Azure AD

Die Authentifizierung an Azure Active Directory (AAD) kann mit ADAL oder mit Management Certificates erfolgen.

Die Variante mit Management Certificates beleuchten wir genauer in Teil 2.
Die Verwendung von ADAL erfordert natürlich die entsprechende Bibliothek.

ADAL kann über NuGet Console oder den NuGet Manager bezogen werden:

Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory -Version 1.0.3

Die ADAL-Versionen 2.5.1 und 2.6.1 sind noch Alpa, Version 1.0.3 ist die last stable Version.

image

Nun kanns mit dem eigenen Projekt und den Azure Management Libraries losgehen.

Um ADAL zu verwenden sind einige Schritte im Azure Portal erforderlich – klar, denn zuerst benötigen wir die Subscription und eine App, die im AAD angelegt wird, damit diese auch berechtigt wird, Services zu nutzen.

Brady hat dafür ein kurzes Video-Tutorial Microsoft Azure Management Libraries Demo Project Tutorial auf YouTube bereitgestellt, wo er die Schritte für die Nutzung von ADAL (App-Erstellung und Beschaffen der erforderlichen IDs…) zeigt.

image

Weiter geht es in Teil 2 mit der Inbetriebnahme des build2014-MAML-EnablingSaaS Beispiels von Brady und den dafür erforderlichen Schritten.

Manfred Steyer: EF 6.1: Datenbanksitzung mit IDbConnectionInterceptor mit Custom-SQL initialisieren

Entity Framework 6.1 bringt eine ganze Menge neuer Interceptoren, mit denen der Entwickler seine eigenen Routinen einklinken kann. Einer davon ist der DbConnectionInterceptor, der Methoden anbietet, die zum Beispiel Entity Framework vor sowie nach dem Öffnen bzw. Schließen einer Datenbankverbindung ausführt.

Mit diesem Interceptor kann der Entwickler Entity Framework anweisen, im Zuge jedes Verbindungsaufbaus bestimmte Befehle an die Datenbank zu senden. Das könnten Befehle zum Initialisieren der Verbindung sein oder Befehle, die temporäre Tabellen erzeugen. Ob letzteres von guter Architektur zeugt, sei an dieser Stelle dahingestellt.

Um einen DbConnectionInterceptor bereitzustellen, implementiert der Entwickler das Interface IDbConnectionInterceptor. Dieses beinhaltet eine ganze Menge an Methoden. Jene, die nicht benötigt werden, erhalten einen leeren Body.

class CustomDbConnectionInterceptor : IDbConnectionInterceptor
{

     […]

}

Von Interesse für die eingangs erwähnte Aufgabenstellung ist die Methode Opened, welche – wie der Name schon vermuten lässt – Entity Framework nach dem Öffnen einer Datenbankverbindung ausführt. Das nachfolgende Listing zeigt eine Implementierung dieser Methode, welche eine temporäre Tabelle erstellt und in diese den Namen des aktuellen Benutzers einträgt. Somit können zum Beispiel Trigger oder Stored Procedures auf den aktuellen Benutzernamen zugreifen.

public void Opened(System.Data.Common.DbConnection connection, DbConnectionInterceptionContext interceptionContext)
{
           
    using (var cmd = connection.CreateCommand())
    {
        cmd.CommandText = "create table #userInfo(userName varchar(255)); insert into #userInfo values(@userName);";
 
        var param = cmd.CreateParameter();
        param.Direction = System.Data.ParameterDirection.Input;
        param.DbType = System.Data.DbType.String;
        param.ParameterName = "userName";
        param.Value = Thread.CurrentPrincipal.Identity.Name;
 
        cmd.Parameters.Add(param);
 
        var result = cmd.ExecuteNonQuery();
        Debug.WriteLine(result);
    }
 
}

Um einen DbConnectionInterceptor bei Entity Framework zu registrieren, übergibt der Entwickler eine Instanz davon innerhalb der verwendeten DbConfiguration an AddInterceptor.

class MyConfiguration: DbConfiguration
{
    public MyConfiguration()
    {
 
        AddInterceptor(new CustomDbConnectionInterceptor());
    }
}

Wer sich daran stößt, dass IDbConnectionInterceptor so viele zu implementierende Methoden mit sich bringt, kann auch von TransactionHandler ableiten. Diese abstrakte Basisklasse implementiert u. a. den IDbConnectionInterceptor mit leeren Methodenkörpern. Somit muss der Entwickler nur mehr die benötigten Methoden überschreiben. Allerdings zwingt der TransactionHandler seinen Derivaten auch eine Methode BuildDatabaseInitializationScript auf, welche jedoch im einfachsten Fall wie nachfolgend gezeigt implementiert werden kann.

class CustomTransactionHandler : TransactionHandler
{
    public override string BuildDatabaseInitializationScript()
    {
        return null;
    }
 
    public override void Opened(
             DbConnection connection,      
             DbConnectionInterceptionContext interceptionContext)
    {
        […]           
    }
}

Zum Registrieren des TransactionHandlers verwendet der Entwickler innerhalb der zu verwendenden DbConfiguration die Methode SetTransactionHandler.

class MyConfiguration: DbConfiguration
{
    public MyConfiguration()
    {
 
        SetTransactionHandler(
            SqlProviderServices.ProviderInvariantName, 
            () => new CustomTransactionHandler());
 
    }


}

codefest.at [MS]: Buntes für Web-Developer: jQuery Rain MultiScreen.js

Passend zu Ostern gibts was Buntes für Web-Developer: jQuery Rain MultiScreen.js. Das ist ein kleines, schlankes jQuery PlugIn, das eine Single Webpage effektvoll und einfach mit Animationen in mehrere Seiten aufteilt und präsentiert.

Auf GitHub kann die letzte Version von Multi-Screen.js von Autor Ian de Vries downgeloadet werden. Mit Multi-Screen.js können Animationen und Timing zwischen den einzelnen Screens eingestellt werden, das Demo zeigt einige mögliche Animationen.

jQuery Rain MultiScreen.js ist einfach in der Verwendung und eignet sich u.a. gut für kleine Websites (Single Page Apps), Anleitungen und Wizards oder auch einfach nur zum animierten Umschalten zwischen Bereichen (<div>-Objekten).

image

Das PlugIn ist klein: multi-screen.min.js ist 27KB groß, das optimierte multi-screen.min.js nur 7KB groß und multi-screen-css nur 1KB. Im HTML <head> müssen nur jQuery und multi-screen.js eingebunden werden und dieses dann nach dem Laden aufgerufen werden.

<link href="../multi-screen-css.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
<script type="text/javascript" src="multi-screen.js"></script>
<script type="text/javascript">$(document).ready(function() { MultiScreen.init(); });</script>

Die Verwendung erfolgt dann im <body> pro Screen so:

<div id="screen1" class="ms-container ms-default">
    <p>some content...</p>
</div>

…und wird dann mit Animationen aufgewertet:

image

Eine kleine HTML-Demo Seite mit Links zwischen zwei “Screens” (<div>) sieht dann vollständig sinngemäß etwa so aus:

<body>
    <div id="screen1" class="ms-container ms-default" style="background-color: red; padding: 2em;">
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>
        <!-- animations -->
        <a class="ms-nav-link" data-ms-target="screen2" data-ms-exit-animation-time="700" data-ms-enter-animation-time="300" href="#">previous</a>
        <a class="ms-nav-link" data-ms-target="screen2" href="#">next</a>
    </div>
    <div id="screen2" class="ms-container" style="background-color: green; padding: 2em;">
        <p>Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.</p>
        <!-- specific animations -->
        <a class="ms-nav-link" data-ms-target="screen1" data-ms-animation="fadeleft" data-ms-vertical-distance="0" href="#">previous</a>
        <a class="ms-nav-link" data-ms-target="screen1" data-ms-delay="true" href="#">next</a>
    </div>
</body>

Klein, schlank und effektvoll – ein nettes jQuery PlugIn um Websites aufzuteilen und ansprechend zu animieren,

Viel Spaß beim bunten Basteln!

ppedv Team Blog: ASP.NET Gridview per JQuery befüllen

Folgende Ausführungen sind rein akademischer Natur. Über den Nutzen für die Praxis kann an der ein oder anderen Stelle diskutiert werden. Trotzdem sitze ich mit offenen Mund davor und frage mich noch immer –“das geht ?”

Wenn über moderne Web Anwendungen gesprochen wird, geht es immer um einen REST Service, JSON Daten und einen HTML View der z.B. mit Hilfe von Angular.js befüllt wird. Alles schön getrennt. Ich breche mit allem.

Als Backend kommt eine Webmethod zum Einsatz. Dieser wird direkt in die ASPX Seite eingebaut. Theoretisch auch im ASPX Teil direkt oder per Codebehind. Die Daten verpacke ich gleich in das Zielformat. Da dies eine HTML Table ist, TR und TD Element. Klassisches XML also. Dank HTTP Compression werden vermutlich auch nicht mehr Daten als im Vergleich zu JSON gesendet.

Die Daten kommen aus der Nordwind Datenbank und werden ganz klassisch per ADO.NET ausgelesen. Also auch hier kein Entity Model. Wichtig der SQL Parameter um SQLInjection zu unterbinden.

In meinem Beispiel wird immer nur ein Datensatz gelesen. Die ID wird über den Querystring eingesteuert und mit ein wenig Magie, dank neuer Funktion ASP.NET FriendlyUrls im Methodenrumpf zugewiesen.

Wer sich bei Zeile 13 die ungläubig die Augen reibt. Das sind XML Literals, ein VB.NET Sprachfeature.

   1:  Public Class WebForm8
   2:      Inherits System.Web.UI.Page
   3:   
   4:      <WebMethod()>
   5:      <ScriptMethod(UseHttpGet:=True, ResponseFormat:=ResponseFormat.Xml)>
   6:      Public Shared Function loadeins(<QueryString("id")> id As Integer?) As XElement
   7:          Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings
("NorthwindConnectionString").ConnectionString)
   8:          Dim cmd As New SqlCommand("SELECT top 1 [ProductID],[ProductName], 
[CategoryID] FROM [Products] where productid=@id"
, con)
   9:          cmd.Parameters.Add(New SqlParameter("@id", id))
  10:          con.Open()
  11:          Dim dtr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
  12:          dtr.Read()
  13:          Dim tablexml = <tr><td><%= dtr(0) %></td>
  14:                             <td><%= dtr(1) %></td>
  15:                             <td><%= dtr(2) %></td>
  16:                         </tr>
  17:   
  18:          Return tablexml
  19:      End Function

 

Die Methode kann per GET aufgerufen werden und liefert XML zurück (Zeile5).

Als nächstes wird ein GridView in die HTML Seite deklariert. Da keine Daten direkt gebunden werden, muss das Attribut ShowHeaderWhenEmpty gesetzt werden.

   1:  <button onclick="loadmeins();return false" type="button">lade</button>
   2:  <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
   3:      ShowHeaderWhenEmpty="true">
   4:      <Columns>
   5:         <asp:BoundField DataField="ProductID" HeaderText="ID" />
   6:         <asp:BoundField DataField="ProductName" HeaderText="Name" />
   7:         <asp:BoundField DataField="CategoryID" HeaderText="i" />
   8:      </Columns>
   9:  </asp:GridView>

Jetzt kommt der einzige Teil bei dem ich mich schmutzig fühle. Code der einzig dem Zweck dient fehlendes zu umgehen. Ohne Daten tut das Gridview nämlich nichts. Also völlig sinn frei im Pageload  eine Liste zuweisen.

   1:   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
   2:      GridView1.DataSource = New List(Of String)
   3:      GridView1.DataBind()
   4:   End Sub

Nun fehlt nur noch das JavaScripts Zeugs, glattgebügelt mit JQuery. Der Aufruf der WebMethod erfolgt mit Page und Methodenname. Der Parameter für den gewünschten Datensatz wird im Data Block mitgegeben. Für die Anforderung muss der ContentType noch auf Json stehen, aber die Rückgabe ist XML. Trotzdem wird hier Text in DataType angegeben, weil dann result in Zeile 10 gleich ein Textstring und kein XMLDocument ist. Spart eine Zeile Code.

Am coolsten ist aber die Methode in Zeile 11. Mit einer einzigen Zeile wird der TR TD String an die Tabelle angehängt und zwar an den ersten TR. Also in der Reihenfolge genau anders rum wie gewohnt.

   1:  var id = 0;
   2:  function loadmeins() {
   3:    id++;
   4:    $.ajax({
   5:        type: "GET",
   6:        url: "webform8.aspx/loadeins",
   7:        data: { id: id },
   8:        contentType: 'application/json; charset=utf-8',
   9:        dataType: 'text',
  10:        success: function (result) {
  11:           $('#<%=GridView1.ClientID%> tbody tr:first').after(result);
  12:        },
  13:        error: function(result)
  14:           {
  15:                   alert("Fehler");
  16:                  }
  17:      });
  18:  }

 

Bei jedem Click auf “lade” wird eine neue Zeile eingefügt.

image

So und nun kommt der Teil wo ich nur staunen kann. Im HTML Source besitzt die Tabelle keinen Tbody. Im DOM allerdings schon (über F12 zu erforschen).

Paul Mizel: Wie lösche ich Projekte oder Collections auf dem VisualStudio Online TFS?

Hab mich letztens bei einem Projekt vertippt und hatte einige Testprojekte im TFS, wollte aufräumen, hab in der Oberfläche nichts gefunden...nach etwas Suche hab ich hier die Lösung gefunden.

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE>

tfsdeleteproject.exe /force /collection:https://{Benutzer}.visualstudio.com/DefaultCollection "ProjektName"

ppedv Team Blog: JQuery und Checkbox Rätsel

Liebe Community, ich habe einen JavaScript Fehler und die Lösung dazu. Allerdings suche ich noch nach der Erklärung. Die Lösung entweder per Facebook facebook.com/preishuber oder per Mail an hannesp AT ppedv.de,

Eine Website funktioniert manchmal und manchmal nicht korrekt, Konkret sind es Checkboxen in einer Tabelle. Die Tabelle kommt aus einem Web Server GridView Control. Dort sollen mittels einer Checkbox in der Header Zeile, alle Checkboxen in den Table Rows an bzw. abgehakt werden. Das funktioniert aber genau zweimal, nicht öfter.

Auf dem Weg zur Lösung wurde das Problem isoliert und mit identen Verhalten nachgestellt.

   1:  <asp:CheckBox ID="CheckBox1" runat="server"/><br />
   2:  <asp:CheckBox ID="CheckBox2" runat="server" /><--click
   3:  &lt;script>
   4:      $('#<%=CheckBox2.Clientid%>').click(function (args) {
   5:      $('#<%=CheckBox1.ClientID%>').attr('checked', args.target.checked);
   6:              });
   7:  </script>

 

Und in der Tat, es klappt nur einmal bzw zweimal, je nach Ausgangsdaten. Die obere Checkbox “folgt” der unteren.

image

Erst wenn man statt attr prop verwendet, klappt es dauerhaft. image

Weder debuggen, noch HTML Source Code noch die Browser Tools haben  geholfen den Fehler zu finden. Es war purer Zufall und ausprobieren. In diesem Fall war es auch nicht möglich der Suchmaschine ein vernünftige Frage zu stellen.

Also liebe Community- Warum ist das so?

[UPDATE} Stephan Hüwe weist mich auf die Doku hin

The difference between attributes and properties can be important in specific situations. Before jQuery 1.6, the .attr() method sometimes took property values into account when retrieving some attributes, which could cause inconsistent behavior. As of jQuery 1.6, the .prop() method provides a way to explicitly retrieve property values, while .attr() retrieves attributes.

Mein Statement dazu: kann man akzeptieren. Allerdings ist eine API die nicht konsistente Ergebnisse liefert –“not well designed” wie es die Briten sagen würden.

codefest.at [MS]: Apps für spielerische Ostern

Heute, rechtzeitig zum anstehenden Osterwochenende, gibt’s für euch ein paar lustige Ostergame-Apps, nämlich Easter Bunny Hop, Rail Rush, Easter Egg Hunt und Enigmatis 2.

Win8 logo

 Easter Bunny Hop (Windows) (1)

EASTER BUNNY HOP 

Hüpfen und hoppeln mit dem fröhlichen Hasen Peter Cottontail. Wer dem kleinen Hasen hilft so hoch wie möglich zu springen, wird mit ein paar bunten Ostereiern belohnt. Die App Easter Bunny Hop besticht nicht nur durch den süßen Hauptdarsteller, sondern auch durch ihre einfache Steuerung.

ENIGMATIS 2: Die Nebel von Ravenwood

Enigmatis: Die Nebel von Ravenwood ist die Fortsetzung des Superhits Enigmatis: Die Seelen von Maple Creek. Diese Detektiv-Geschichte steckt voller Schrecken, überraschender Wendungen und dunkler Geheimnisse – wer also nicht unbedingt auf ein Hoppelhasen-Spiel aus ist und auf der Suche nach einem spannenden Abenteuer für die Osterfeiertage sucht, ist bei Enigmatis genau richtig. Das Spiel enthält handgezeichnete Locations und Grafiken mit zahlreichen Animationen. Derzeit bekommt man 30% Nachlass auf den Kaufpreis der Vollversion – die Testversion ist natürlich kostenlos!

Ich hab selbst noch nicht Zeit gehabt, das Game durchzuspielen, habe jedoch schon einige Empfehlungen dafür erhalten. Ich kann’s kaum erwarten diese Detektivgeschichte durchzuspielen – da kommen mir die Feiertage ganz gelegen. 

Enigmatis 2 Logo

das perfekte ei logo

DAS PERFEKTE FRÜHSTÜCKSEI

Die letzte Windows App für heute ist ausnahmsweise kein Spiel, sondern ein nützliches Tool für’s Eier-Kochen. In der App kannst du ein paar Parameter festlegen, z.B. wie hart bzw. weich das Ei werden soll oder welche Temperatur das Ei derzeit hat. Mit dieser App wird Eierkochen zum Kinderspiel und das perfekte Ei für das Frühstück am Ostersonntag ist gesichert.

 
windows-phone-logo_thumb521
rail rush logo
QR - rail rush

RAIL RUSH

Steig in deinen Minenwagen und los geht’s mit diesem aufregenden Abenteuer! Versuche Hindernissen, wie z.B. auf dich zurollende Riesen-Ostereier, auszuweichen. Sammle auf deiner Fahrt Goldbarren und glänzende Edelsteine ein und kauf damit besseres Equipment oder Helden wie z.B. Danny Bunny, der dir dabei hilft, die Riesenostereier zu zerstören. Insgesamt gibt es neun verschiedene Welten wie z.B. Crazy Caves, Sweet Wonderland, Amazon Jungle or the Undersea World. Zusätzlich kommen noch weitere Überraschungslevel auf dich zu. Es gibt 17 verschiedene Charaktere, mit denen du dich auf dein Abenteuer begeben kannst. Das Spiel besticht mit einer tollen Grafik und intuitiver Steuerung. Für eine limitierte Dauer gibt es derzeit ein Oster-Update.

 

 

EASTER EGG HUNT

Wie der Titel dieses Spiels schon verrät, geht es darum, alle versteckten Ostereier zu entdecken. Insgesamt gibt es neun verschiedene Ostereier-Suchseiten. Einfach auf das Ei tippen und einsammeln – eine echte Schlechtwetter-Alternative für den Ostersonntag.

Easter Egg Hunt Windows Phone (3)_VIE-MILOHE_1QR - easter egg hunt

Habt ihr App-Empfehlungen für die Ostertage für uns? Lasst es uns bitte in einem Kommentar wissen.

Frohe Ostern und viel Spaß beim Spielen!

Falco Ostermann: Mobile Anwendungsszenarien mit SharePoint 2013 – Wie und Warum?

SharePoint 2013 hält aufgrund der vielseitigen Integrationsmöglichkeiten in immer mehr Unternehmen Einzug als die zentrale Datendrehscheibe. Hauptzugriffskanal darauf ist heute mit Sicherheit noch der klassische Desktop (PC oder Notebook). Im privaten Umfeld erfahren Apps auf mobilen Geräten jedoch immer höhere Akzeptanz und sind dabei sogar teilweise gleichauf mit der klassischen Webseite. Facebook oder auch die Deutschen Bahn werden mittlerweile fast nur noch mobil über Apps oder einer mobilen Webseite aufgerufen. Betrachtet man die von Facebook veröffentlichten Nutzerzahlen für Deutschland, so ergibt sich folgendes Bild:

Aus dieser Darstellung geht hervor, dass auf Facebook fast ausschließlich nur noch mobil zugegriffen wird. Dieser Trend setzt sich in der Arbeitswelt fort und sollte von Unternehmen bei der IT Planung berücksichtigt werden. Aus diesem Grund ist es nicht verwunderlich, dass Mitarbeiter immer häufiger SharePoint auch mobil nutzen wollen. Welche Vor- und Nachteile, neben den von SharePoint angebotenen mobilen Ansichten, Windows 8 Apps auf Tablets haben und was dabei zu beachten ist, soll in diesem Artikel genauer betrachtet und vorgestellt werden.

Warum mobile Anwendungen und keine mobilen SharePoint Ansichten?

SharePoint 2013 stellt standardmäßig Mobile Ansichten zur Verfügung, welchen den mobilen Zugriff ermöglichen. Zusätzlich kann mit Hilfe von Mobile Device Channels für unterschiedliche Geräte entsprechende Gestaltungsvorlagen konfiguriert werden. Vermutlich erfüllt das die meisten Anforderungen von Unternehmen, wenn da nicht so ein kleines “aber” wäre. Dieses vorgehen empfiehlt sich nur für Inhalte, welche lediglich lesend zur Verfügung gestellt werden sollen. Ein klassischer Anwendungsfall dafür ist eine mobile Ansicht für ein Internet- oder Intranet-Portal. Denn dieses kann zum einen über den klassischen Desktop, aber auch über mobile Geräte aufgerufen werden.

Um allerdings in einem Unternehmen die mobile Produktivität zu steigern, muss eine Bearbeitung von Inhalten auf mobilen Geräten sichergestellt sein. Und damit befinden wir uns bei mobilen Anwendungen auf Tablets oder Phones mit iOS, Android oder Windows als Betriebssystem. Durch den Zugriff auf das Filesystem, können mittels mobiler Anwendungen Dokumente offline mitgenommen, bearbeitet und zu einem späteren Zeitpunkt im SharePoint aktualisiert werden. Des Weiteren kann eine bessere Integration in das Bedienkonzept des entsprechenden Gerätes erfolgen, was sich unter anderem durch die Verwendung von Notifications oder Live Tiles auszeichnet. Dadurch ist der Anwender stehts informiert, egal ob er sich gerade am Dekstop befindet oder mobil unterwegs ist.

Welche Schnittstellen bieten sich an?

Durch die Einführung von SharePoint Apps wurden entsprechend die Schnittstellen erweitert und modernisiert. Demnach empfehlen sich für eine mobile Anwendung die folgenden Schnittstellen:

  • CSOM (SharePoint-ClientObjektmodell)
  • REST (Representational State Transfer)

Durch die Einführung der REST-Schnittstelle können mobile Anwendungen zusätzlich zu den Betriebssystemen Windows 8 und Windows Phone auch auf iOS, Android und auf BlackBerry bereitgestellt werden. Auch ist es mit REST möglich, Informationen von einer SharePoint 2013 OnPremise- oder SharePoint 2013 Online-Umgebung mit der gleichen Syntax zu beziehen. Das spart natürlich auf den ersten Blick Entwicklungsaufwand, aber:

Bei CSOM handelt es sich um eine typisierte Schnittstelle, wie man es mit C# standardmäßig gewohnt ist und dadurch schnell zum Ziel gelangt. REST wiederum liefert als Ergebnis ein JSON, welches nachträglich für den einfachen Zugriff typisiert werden muss. Da es sich bei JSON um eine JavaScript Notation in Form von Text handelt, muss die gewohnte Arbeitsweise mit C# angepasst werden. Um aber REST und JSON trotzdem typisiert (analog zu C#) aufrufen zu können, werden bereits entsprechende Helper zum Casten in der Community angeboten bzw. müssen individuell entwickelt werden. Damit erhöht sich gegebenenfalls der Entwicklungsaufwand einer mobilen Anwendung unter Verwendung der REST-Schnittstelle, könnte aber dadurch auf unterschiedlichen Betriebssystem verwendet werden.

Bei der Bereitstellung von Windows 8 Anwendungen kann auch auf die CSOM-Schnittstelle zurückgegriffen werden. Soll jedoch diese Anwendung im Windows Store für andere zur Verfügung stehen, so muss ebenfalls die REST-Schnittstelle verwendet werden, da in diesem Fall die CSOM-Schnittstelle nicht erlaubt ist.

Als Zwischenfazit sei hier bereits gesagt, dass es sich immer empfiehlt die REST-Schnittstelle wenn möglich zu verwenden. Zum einen wegen der oben genannten Punkte, aber auch im Hinblick auf Zukunftssicherheit.

Was gilt es zu beachten?

Natürlich gilt es bei der Entwicklung und Bereitstellung einer mobilen Anwendung für Windows 8 folgendes zu beachten:

  • es muss für den Anwendungsfall entsprechend die richtige Schnittstelle ausgewählt werden
  • es muss für die Unterstützung von SharePoint 2013 OnPremise oder SharePoint 2013 Online jeweils eine eigene Authentifizierung geschrieben werden. Dabei ist zu beachten, dass dieser Domain-Übergreifend funktioniert und ein Single-Sign-On mittels Windows Authentifizierung nicht vorausgesetzt werden darf
  • Um Offline-Funktionalität anbieten zu können, muss die Anwendung auch ohne Internetverbindung funktionieren
  • Sollen Office-Dokumente von SharePoint heraus mit dem Office-Client geöffnet werden, so dürfen diese nicht erst lokal heruntergeladen werden. Dazu muss folgender Ansatz gewählt werden, was leider die wenigstens Windows 8 Anwendungen machen
  • Ist eine Windows 8 Anwendung auf den einzelnen Clients verteilt, so können Anpassungen nur über Updates eingespielt werden, was eine gewisse Zeit in Anspruch nehmen kann

Fazit

SharePoint 2013 bietet mit den mobilen Ansichten einen guten Ausgangspunkt um das Portal für den mobilen lesenden Zugriff zur Verfügung zu stellen. Wenn aber mit der Einführung einer mobiler Infrastruktur auch die mobile Produktivität verbessert werden soll, muss auf mobile Anwendungen zurückgegriffen werden. SharePoint 2013 bieten mit REST eine Plattform übergreifende Schnittstelle, welche auf einem SharePoint 2013 OnPremise und SharePoint 2013 Online verwendet werden kann. Da mobile Anwendungen Zugriff auf das Filesystem des mobilen Gerätes haben, können so Dokumente offline bearbeitet und zu einem späteren Zeitpunkt im SharePoint aktualisiert werden. Außerdem ist es damit möglich, Wartezeiten wie am Bahnhof oder vorm Boarding sinnvoll zu nutzen. Und das auch ohne Internet! Ich persönlich empfinde mobile Anwendungen bei meiner täglichen Arbeit als sehr nützlich und hoffe euch damit ebenfalls überzeugt zu haben :-)

Uli Armbruster: Wo findet sich der Quality Manager in Scrum wieder?

Kürzlich sprach ich mit einer Bewerberin, die während ihres Studiums erste Erfahrungen mit Scrum in einem größeren Betrieb gemacht hat. Mit Interesse verfolgte ich ihre Antwort auf die Frage, wie die konkrete Implementierung aussah. Dabei fielen die Bezeichnungen Product Manager und Quality Manager.

Das ist insofern interessant, weil Scrum die beiden Rollen gar nicht kennt. Während der klassische Product Manager in den 3 Rollen Product Owner, Scrum Master und Developer Team aufgeht, sieht das beim Quality Manager anders aus. Wie schon beim Lean Management steckt der Gedanke hinter Scrum, dass die Qualität nicht zum Schluss durch eine Person geprüft werden, sondern dass Qualität im kompletten Entwicklungsprozess von jedem Beteiligten als eigener Anspruch etabliert werden soll. Im Falle eines Autos würde das bedeuten, dass nicht erst das fertige Auto am Ende der Fertigungsstraße auf Qualität geprüft wird. Stattdessen soll kontinuierlich vom Start bis zum Ende an jeder einzelnen Fertigungsstelle der Bearbeiter über die Standards Bescheid wissen und sie kontrollieren. Sollte währenddessen das Produkt dem Anspruch nicht genügen, würde die Fertigungsstraße pausiert und darüber beraten werden, wie es mit dem Fahrzeug weitergehen soll. Kurz gesagt: Wenn das Kind in den Brunnen gefallen ist, muss nicht mehr über die Absicherung des Brunnens gesprochen werden.

Besagter Gedanke wird in Scrum zum Einen über die Definition of Done etabliert. Eine User Story darf erst als erledigt gekennzeichnet werden, wenn der Definition entsprochen wurde. Darin stehen unter anderem Spezifikationen für die automatisierte Testabdeckung, sowie etwaige manuell durchzuführende Tests. Im Übrigen finden sich dort auch Aussagen zur Sicherheit, weil das Absichern einer Anwendung im Nachhinein genauso wenig zielführend ist wie im Falle der Produktqualität.

Darüber hinaus gehört zu einem erfolgreichen Scrum Prozess auch ein Build Server, der automatisiert alle Arten von Tests durchführt und bei jedem Check-In im Versionskontrollsystem (auch das VKS ist Teil der Qualitätssicherung) alle Produktteile integriert.

Das bedeutet, dass die Aufgaben des Quality Managers in Scrum an das Entwickler Team übergehen. Das Team soll schließlich eigenverantwortlich arbeiten und gerade hier zeigt sich, ob sich der Product Owner das richtige Team für seine Vision herausgesucht hat. Oder aber es zeigt sich, dass dem Team gar nicht erlaubt wird so zu arbeiten, wie es das für richtig hält. Hier ist dann der Scrum Master gefragt. Beispielsweise habe ich von Teams gehört, denen der Build Server und das Versionskontrollsystem vorgeschrieben wurde, obwohl die Entwickler klar kommunizierten, dass die Software nicht den Ansprüchen genügt.


Einsortiert unter:CIO Topics, Development, German Tagged: Scrum

ppedv Team Blog: Breadcrumb-Ansicht in SharePoint 2013

Um in SharePoint 2013 die von vielen Menschen liebgewonnene Breadcrumb-Ansicht oder anders ausgedrückt Brotkrümel-Ansicht anzuzeigen, wird im folgenden Artikel die Vorgehensweise beschreiben.

Es empfiehlt sich den SharePoint Designer 2013, nachfolgend SPD 2013 genannt, hierfür zu benutzen.

Hinweis: Damit die nachfolgenden Schritte funktionieren, ist es zuvor notwendig, die nachfolgend als Screenshot aufgeführten Features einzuschalten. Darüber hinaus muss auch eine entsprechende Website-Struktur erstellt worden sein (Untersites) und die Navigationseinstellungen bearbeitet worden sein (Unterwebsites anzeigen aktivieren)

1. Homepage aufrufen (Website der obersten Ebene), Features aktivieren

Einstellungen -> Websiteeinstellungen -> Websitesammlungsverwaltung -> Websitesammlungsfeatures -> SharePoint Server-Veröffentlichungsinfrastruktur

clip_image002

Einstellungen -> Websiteeinstellungen -> Websiteaktionen -> Websitefeatures verwalten -> SharePoint Server-Veröffentlichung

clip_image004

Hinweis: Das SharePoint Server-Veröffentlichungsfeature muss auf jeder Unterwebsite aktiviert werden. Des Weiteren ist die Navigationsvererbung einzuschalten.

2. Nachdem die Verbindung im SPD 2013 hergestellt worden ist, wird im Navigationsbereich links unter Websiteobjekte der Punkt Gestaltungsvorlagen aufgerufen.

3. Standardmäßig wird die seattle.html Masterpage verwendet. Hier gilt es die seattle.html aufzurufen, nicht die seattle.master.

Nun sucht man im Code am besten mittels Tastenkombination Strg + F nach „ms-breadcrumb-box

clip_image006

4. Hier wird die Eigenschaft unter „Visible“ statt false auf „true“ gesetzt.

5. Danach wird in der Code-Ansicht nach der passenden Stelle gesucht, an der die folgenden zwei Code-Zeilen eingefügt werden:

<!--MS:<asp:sitemappath runat="server" sitemapproviders="SPSiteMapProvider,SPXmlContentMapProvider" rendercurrentnodeaslink="false" hideinteriorrootnodes="true">-->

<!--ME:</asp:sitemappath>-->

In meinem Beispiel habe ich die Breadcrumb-Ansicht unterhalb des Titels der jeweiligen Website eingefügt. Der Bildausschnitt zeigt, an welcher Stelle es vorgenommen werden muss.

clip_image009

Jetzt wird die Masterpage gespeichert und die Website aktualisiert. Das fertige Ergebnis sieht dann folgendermaßen aus:

clip_image012

Unterhalb des Titels wird als Pfad angezeigt, welche Unterwebsites geöffnet wurden.

codefest.at [MS]: Spannendes aus der Windows Phone Welt

Große Windows Phone Fans wissen wahrscheinlich schon, dass es seit einigen Monaten in Wien ein Windows Phone Developer After-Work gibt. Nach den erfolgreichen ersten beiden Veranstaltungen, kommt nun das nächste Event, das die Mopius und Tieto organisieren.

Diesmal wird das Mobile Developer After Work noch größer und spannender abgehalten. Diesmal warten soviele spannende Vorträge auf euch, dass ihr 3 Tracks zum Besuchen als Auswahl habt. Im ersten Track sind viele spannende Themen für Windows Phone beleuchtet. Im zweiten Track könnt ihr euch Nokia X ein bisschen näher anschauen. Der dritte Track ist ein Porting Camp, bei dem ihr bestehende Android Apps auf die Nokia X Platform portieren könnt.

Da sich diesmal die Teilnehmeranzahl stark erhöht hat, wird das Developer After-Work bei uns im Microsoft Office abgehalten. Dieses Event ist auch eine tolle Gelegenheit, sich mit anderen Mobile Developern auszutauschen und die neuesten Entwicklungen zu diskutieren.

Wenn ihr in der mobile app Entwicklung tätig seid und noch nie bei einem Windows Phone Developer After-Work dabei wart, ist das eine super Gelegenheit, die Community kennenzulernen. Einige Restplätze gibt es noch: schnell anmelden, lohnt sich!

Manfred Steyer: Validieren internationalisierter Eingaben mit AngularJS

Während AngularJS die Internationalisierung von Ausgaben erlaubt, bietet es (derzeit noch) keine Unterstützung für das Erfassen von Eingaben, die internationalisiert vorliegen. Allerdings gibt AngularJS dem Entwickler die Möglichkeit, benutzerdefinierte Validatoren festzulegen. Daneben kann der Entwickler angeben, wie die erfassten Eingaben für die Verwendung im Model aufzubereiten sind. Somit kann zum Beispiel der von einem deutschen Benutzer erfasste String „47,11“ im Model durch eine Eigenschaft vom Typ number mit dem Wert 47.11 repräsentiert werden. 

Zum Definieren eigener Validatoren implementiert der Entwickler eine benutzerdefinierte Direktive. Dazu nutzt er die Funktion directive, welche AngularJS auf Modul-Ebene anbietet. Der erste Parameter ist der Name der Direktive; der zweite Parameter erwartet eine Funktion, die ein Objekt zurückgibt, das die Direktive beschreibt. Die Eigenschaft require dieses Objekts legt fest, dass die hier definierte Direktive nur für Felder, die auch die Direktive ng-model nutzen, verwendet werden darf. Dies macht sinn, denn ng-model kümmert sich schließlich um die Datenbindung. Die Eigenschaft link verweist auf eine Funktion, welche die Direktive für ein Feld aktiviert. Über ihre Parameter erhält diese Funktion von AngularJS den aktuellen Scope (scope), ein jQuery-Objekt, das das auf die Direktive angewandte HTML-Element repräsentiert (elm), ein Objekt, welches die Attribute dieses Elements beinhaltet (attrs), sowie ein Objekt, welches das Steuerelement im Form-Controller repräsentiert.

Die Direktive im nachfolgenden Listing prüft unter Verwendung von Globalize (https://github.com/jquery/globalize), ob die Eingabe des Benutzers einer Zahl entspricht, die entsprechend der aktuell gewählten Kultur formatiert wurde. Um das gewünschte Format zu ermitteln, greift link auf den Wert des Attributes gnumber zu. Dabei ist zu beachten, dass dieses Attribut denselben Namen wie die Direktive hat und somit jenen Wert aufweist, der der Direktive zugewiesen wurde. 

Anschließend richtet link für das Eingabefeld einen Parser sowie einen Formatter ein. Bei beiden Konzepten handelt es sich um Funktionen. Ein Parser ist eine Funktion, die die Eingabe des Benutzers parst. Dabei kann sie dem Steuerelement mitteilen, ob die Eingabe korrekt validiert werden konnte, indem sie dessen Funktion $setValidity verwendet. Der erste Parameter von $setValidity ist der Name der Validierungslogik; der zweite Parameter zeigt an, ob ein Validierungsfehler aufgetreten ist. Jenen Wert, den der Parser zurückgibt, schreibt AngularJS zurück ins Model. Auf diese Weise kann die link-Funktion veranlassen, dass Benutzereingaben nicht nur in Form von Strings sondern in Form anderer Typen in das Model geschrieben werden. Besonders nützlich ist dies bei der Behandlung von Datumswerten, wo das Zurückschreiben eins Date-Objektes wünschenswert ist.

Der Formatter kümmert sich um die Formatierung des Wertes, bevor dieser an das Eingabefeld gebunden wird. Er formatiert den Wert unter Verwendung von Globalize und des an die Direktive übergebenen Formats.

Bei Betrachtung des vorliegenden Quellcodes fällt auf, dass ein Steuerelement mehrere Parser und Formatter besitzen kann, zumal es sich bei den Eigenschaften $parsers und $formatters um Arrays handelt. Dies ist notwendig, zumal pro Steuerelement mehrere Direktiven mit jeweils einer eigenen Validierungslogik verwendet werden können.

 

var app = angular.module("Flug", []);

[…]

app.directive('gnumber', function () {

return {

    require: 'ngModel',

    link: function (scope, elm, attrs, ctrl) {



        var format = attrs.gnumber;



        ctrl.$parsers.unshift(function (viewValue) {



            var number = Globalize.parseFloat(viewValue);

            if (!isNaN(number)) {

                ctrl.$setValidity('gnumber', true);

                return number;

            }

            else {

                ctrl.$setValidity('gnumber', false);

                return undefined;

            }



        });



        ctrl.$formatters.unshift(function (value) {

            var formatted = Globalize.format(value, format);

            return formatted;

        });



    }

};

});

 

Das nachfolgende Listing demonstriert, wie die im letzten Beispiel beschriebene Direktive eingesetzt werden kann. Dazu erhält das zu validierende Input-Element ein Attribut, welches dem Namen der Direktive entspricht. Der Wert dieses Attributes wird auf das Format gesetzt, das Globalize verwenden soll. Um herauszufinden, ob die Validierung erfolgreich war, greift das Beispiel auf die Eigenschaft form.flugNummer.$error.gnumber zu, wobei gnumber jener Bezeichner ist, den die Direktive an $setValidity übergibt.

 

<div>Preis</div>

<div><input ng-model="vm.preis" gnumber="N2" /></div>

<div ng-show="form.flugNummer.$dirty && form.flugNummer.$error.gnumber">

   Muss eine Zahl sein!

</div>

 

Fabian Deitelhoff: Bouncy Castle: was keine Bibliothek verhindern kann

Cover der dotnetpro Ausgabe 05/2014In der Ausgabe 05/2014 der dotnetpro habe ich – im Rahmen der Rubrik “Frameworks” – Bouncy Castle unter die Lupe genommen. Dabei handelt es sich um eine Bibliothek mit kryptographischen Funktionen. Also übersetzt für das Ver- und Entschlüsseln von Daten. Trotz einer guten Bibliothek – und Bouncy Castle ist tatsächlich sehr gut und weit verbreitet – können bei dem sensiblen Thema Verschlüsselung immer wieder Fehler passieren.

Fehler, die auch keine Bibliothek verhindern kann, wie die Überschrift so schön heißt. Egal wie gut die Bibliothek tatsächlich ist. Denn: nachdenken müssen wir als Entwickler immer noch selber. Auch wenn hin und wieder eine Bibliothek selbst ein Problem hervorrufen kann, wie der Artikel am Ende deutlich macht.

In der folgenden kleinen Auflistung möchte ich auf einige Fehler hinweisen, die mir selber auch schon passiert sind. Weil ich es einfach nicht besser wusste. Da konnte das Framework beziehungsweise die Bibliothek, die ich damals genutzt habe, überhaupt nichts für. War auch nicht alles unter .NET beziehungsweise C#. Trotzdem können die Fehler beliebig oft wiederholt werden :).

Der MD5-Algorithmus ist tabu!

Egal wie wir das drehen oder wenden. Ein MD5-Hashwert gilt schon länger als nicht mehr sicher. 1996 konnte die erste Kollision zweier unterschiedlicher Nachrichten nachgewiesen werden. Seit 2004 ist es möglich, Kollisionen systematisch zu erzeugen. Ein aktueller PC benötigt dazu nur noch Sekunden. Hoch parallele Grafikkarten können hunderte Millionen MD5-Hashwerte pro Sekunde berechnen, so dass die Hashfunktion praktisch als geknackt gilt. Ergo: Finger weg!

SHA1-Hashwerte für Passwörter speichern

Eine weitere Sache, die ich früher gerne gemacht habe. Na ja, nachdem ich MD5 nicht mehr als Hash für Passwörter in einer Datenbank genutzt habe :). An SHA1 ist zunächst nichts auszusetzen. Allerdings ist es schlecht, die reinen Hashwerte abzuspeichern, ohne die Salts. Damit ist eine zufällig generierte Zeichenkette gemeint, die beim Berechnen des Hashwertes für das eigentliche Passwort angehängt wird. Das Problem dabei ist, dass bei einem Angriff gleich eine ganze Reihe von Zugängen kompromittiert sein können. Nämlich alle Accounts, die das gleich Passwort nutzen – was an gleichen Hashwerten ersichtlichen ist. Durch den Salt, der für jeden Account unterschiedlich sein muss, unterscheiden sich auch alle Hashwerte, was einen Angriff deutlich schwieriger macht. 2012 passierte das beim LinkedIn-Hack. Die veröffentlichten Passwörter enthielten keinen Salt und so waren schon nach kurzer Zeit mehr als 60% der Passwörter geknackt.

DES ist veraltet

Auch wenn Bouncy Castle DES (Data Encryption Standard) unterstützt, sollte dieser nicht mehr zum Einsatz kommen. Er wurde mit einer effektiven Schlüssellänge von 56 Bit im Hinterkopf konzipiert, was mittlerweile nicht mehr ausreichend ist. Ich habe den Standard zwar noch im Artikel erwähnt, bin aber nicht näher darauf eingegangen, sondern habe den Nachfolger AES (Advanced Encryption Standard) vorgestellt. Das nicht ohne Grund. Bitte auf DES verzichten.

Auch ECB ist überholt

Mit ECB ist der Electronic Codebook Mode gemeint, der in Blöcken über den unverschlüsselten Eingabetext läuft und einen Block nach dem anderen verschlüsselt. Das Problem an dieser Methode ist, dass dadurch Muster in den Daten nicht mit verschlüsselt werden, sondern anschließend immer noch sichtbar sind. Ein Bildvergleich auf Wikipedia zeigt das sehr deutlich: Abb. 1: Das Originalbild. Abb. 2: Verschlüsselt mit dem ECB-Modus. Abb. 3: Verschlüsselt mit dem CBC-Modus.

Das Problem tritt mit dem CBC-Verfahren (Cipher-block chaining) nicht auf und sollte daher stattdessen zum Einsatz kommen. Bouncy Castle unterstützt beide Modi.

Fehlerhafte & ungenügende Startwerte

Dieses Problem tritt häufiger auf als gedacht. Um verschiedene Zufallszahlen zu erzeugen, ist es wichtig, dass der Generator mit einem zufälligen Seed, also Startwert, initialisiert wird. Gleiche Seeds sollen gleiche Folgen von Zufallszahlen erzeugen, was beispielsweise für die Reproduzierbarkeit in wissenschaftlichen Experimenten wichtig ist. In der Praxis sind gleiche Zufallszahlen selten erwünscht. Insbesondere nicht bei der Verschlüsselung. Die Bibliothek Portable.Licensing, über die ich ebenfalls im Rahmen der Rubrik “Frameworks” geschrieben habe, litt unter so einem Fehler. Um es aber gleich vorweg zu nehmen: seit der Version 1.1.0, die mittlerweile vor über einem Jahr veröffentlicht wurde, ist der Fehler behoben.

Hintergrund des Problems war – beziehungsweise ist – Bouncy Castle. In diesem Fall war die Bibliothek für einen Fehler verantwortlich. Bei der C#-Portierung wird, anders als in der Java-Version, standardmäßig kein Startwert für den Zufallszahlengenerator gesetzt. Wenn also explizit kein Seed gesetzt wird, ist der Startwert statisch. Das ist sehr unschön. Bei Portable.Licensing führt das dazu, dass immer gleiche private und öffentliche Schlüssel erzeugt wurden. Ein schwerwiegender Fehler. An der betreffenden Zeile 41 des C#-Codes von Bouncy Castle ist nur folgender Kommentar zu finden:

// TODO Compared to JDK, we don’t auto-seed if the client forgets – problem?

Ein ToDo-Kommentar… Wer kennt das nicht :). Und wenn es jetzt noch Zeile 42 gewesen wäre… Also immer darauf achten, dass der Seed des Zufallszahlengenerators gesetzt und zufällig ist.

Fazit

Fehler können immer passieren. Eine gute Bibliothek sorgt dafür, dass diese minimiert werden. Allerdings kann ebendiese Bibliothek auch für Fehler verantwortlich sein. Und gegen den Einsatz von fehlerhaften beziehungsweise veralteten Standards und Methoden ist sowieso kein Kraut gewachsen. Da hilft nur die eigene Denkleistung.

Dieser Artikel ist selbstverständlich nur ein kleiner Ausschnitt aus dem Themenbereich der Verschlüsselung. Er erhebt in keinster Weise Anspruch auf Vollständigkeit. Beim Artikel zu Bouncy Castle in der dotnetpro bin ich nur ins Grübeln geraten, was ich früher schon alles falsch gemacht habe und was mir mittlerweile hoffentlich nicht mehr passiert.

Code-Inside Blog: Source Code veröffentlichen – aber bitte mit Lizenz

image.png

Seit es den Blog gibt wird auch meist der gesamte Demo Source Code mit veröffentlicht. Das Ganze hatte ich am Anfang noch als .zip verteilt, später lag es mal auf Google Code und nun liegen alle Samples und sonstige Sachen auf GitHub.

Beim letzten User Group Treffen in Zürich mit dem Titel “Open Source: Get Involved!” mit Adam Ralph wurde mir schlagartig bewusst, dass ich zwar meine Blogposts unter Creative Common gestellt hatte, aber dabei ganz die GitHub Repos vergessen hatte.

Dies hatte ich jetzt nachgeholt und wer Source Code veröffentlicht sollte sich 5 Minuten Zeit nehmen und mal auf der Seite ChooseALicense.com eine passende Lizenz zum jeweiligen Source Code packen – ansonsten ist das ganze rechtlich gesehen ein Minenfeld Winking smile

Christian Giesswein: LOB Business Apps - .NET Broker App und Windows Store Apps

Mit Windows 8.1 Update 1 ist es nun möglich, Side-Loaded Apps (also Apps die am Store vorbei ausgeliefert werden) per „Broker-Mode“ mit einer „alten“ .NET Anwendung interagieren zu lassen. Das bedeutet, für Unternehmenskunden und Unternehmen die eine ganze Reihe an Anwendungen für den In-House Betrieb bereits haben, können die Anwendungen wiederverwenden und dabei sehr schnell eine Windows Store App „herzaubern“ (Stimmt natürlich nur fast..).

Nachdem der gesamte Prozess aber noch sehr undokumentiert und noch sehr viel händisch gemacht werden muss, ein kleines Walkthrough zur Windows Store App mit dem großen .NET Framework und co.

Achtung: Einige Schritte erfordern Administratorenrechte! Visual Studio 2013 also mit Admin-Rechten starten. Weiters wird das Windows 8.1 SDK Benötigt.

Zur Architektur

 

1)      Eine Windows Runtime Component, die zurechtgebogen wird, damit wir mit .NET arbeiten können. Daraus werden sich im weiteren Verlauf zwei Dinge ergeben:

  • Eine „reference“ Komponente - Quasi – das Interface für die Windows Store App
  • Die Implementierung - Dies hat für mich bereits einiges an Verwirrung gesorgt, da die Dateien ident benannt werden müssen aber unterschiedliche Inhalte haben.

2)      Eine C++ Proxy-DLL die automatisch erzeugt wird aber die Kommunikation zwischen Reference und Implementation übernimmt

3)      Die Windows 8.1 App

Die Reiseroute

 

Dementsprechend wird es am Ende mindestens drei Projekte geben.

Zuerst müssen wir uns eine frische Solution anlegen und darin eine Windows Runtime Component. Ich habe diese Komponente mal „NETBroker.LegacyCode“ getauft da hier unser alter .NET Code „gehostet“ wird. In diesem Projekt gibt es anschließend zwei simple Dinge, ein Interface und eine Implementierung des Interfaces. Zu Erst muss aber die *.csproj bearbeitet werden. Hierbei müssen folgende Änderungen vorgenommen werden:

1)      In Zeile 18, muss in der ersten ProerptyGroup folgender Eintrag hinzugefügt werden:

<ImplicitlyExpandTargetFramework>false</ImplicitlyExpandTargetFramework>

2)      In Zeile 105, in dem ItemGroup Knoten müssen die .NET Referenzen hinzugefügt werden:

<ItemGroup>
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\mscorlib.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.ComponentModel.Composition.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Configuration.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Core.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Threading.Tasks.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Runtime.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\Facades\System.Runtime.InteropServices.WindowsRuntime.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Xml.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\System.Data.dll" />
  <ReferencePath Include="C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd" />
  <ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1\System.Runtime.WindowsRuntime.dll" />
</ItemGroup>

Sobald man diese Änderungen übernommen hat, hat man bereits wieder Zugriff auf die .NET Klassen aus den referenzierten Bibliotheken.

Ich habe hier nun folgendes Interface:

[ComVisible(true), Guid("B604ECD3-D034-42C4-B11D-F7E1C8D7F70E")]
public interface ICustomerRepository
{
  IEnumerable<string> GetCustomers();
}

Und folgende Implementierung:

[ComVisible(true), Guid("420541B2-7FF9-4109-BE5B-68BD0351EE41")]
public sealed class CustomerRepository : ICustomerRepository
{
  public IEnumerable<string> GetCustomers()
   {
      using (var sql = new SqlConnection(@"Data Source=(localdb)\Projects;Initial Catalog=Northwind;"))
      {
      sql.Open();
      using (var cmd = sql.CreateCommand())
      {
        cmd.CommandText = "SELECT * FROM CUSTOMERS";
        using (var reader = cmd.ExecuteReader())
        {
           while (reader.Read())
           {
             yield return reader["CustomerId"].ToString();
          }
        }
      }
    }
  }
}

Daher aus einer LocalDB Datenbank per ADO.NET ein SQL-Befehl ausführen und alle Ergebnisse der Kundentabelle zurückgeben (bzw. die IDs davon). Die Klasse als auch das Interface werden jeweils für COM sichtbar gemacht, per Attribute.

Nun steht also unser „legacy“ Code bereits, und wir kümmern uns nun als nächster um den Proxy-Code. Dafür benötigen wir ein simples C++ Projekt. Ich nannte das ganze „NETBroker.Proxy“. Sobald das Template von Visual Studio erzeugt wurde, müssen hier alle Header und CPP-Dateien gelöscht werden. 

So nun wird das ganze etwas knifflig, den C++ Code lassen wir uns vollständig durch Boardmittel erzeugen, dafür ist im .NET Projekt NETBroker.LegacyCode ein POST-Build notwendig.

call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86
md "$(TargetDir)impl"
md "$(TargetDir)reference"
erase "$(TargetDir)\impl\*.winmd"
erase "$(TargetDir)\impl\*.pdb"
rem erase "$(TargetDir)\reference\*.winmd"
xcopy /y "$(TargetPath)" "$(TargetDir)impl"
xcopy /y "$(TargetDir)*.pdb" "$(TargetDir)impl"
winmdidl /nosystemdeclares /metadata_dir:C:\Windows\System32\Winmetadata "$(TargetPath)"
midl /metadata_dir "C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" /iid "$(SolutionDir)NETBroker.Proxy\$(TargetName)_i.c" /env win32 /x86 /h "$(SolutionDir)NETBroker.Proxy\$(TargetName).h" /winmd "$(TargetName).winmd" /W1 /char signed /nologo /winrt /dlldata "$(SolutionDir)NETBroker.Proxy\dlldata.c" /proxy "$(SolutionDir)NETBroker.Proxy\$(TargetName)_p.c" "$(TargetName).idl"
mdmerge -n 1 -i "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" -o "$(TargetDir)reference" -metadata_dir "C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral" -partial
rem erase "$(TargetPath)"

Achtung, hier kommt viermal der Name des C++ Projektes vor, da hier automatisch die Quelldateien hineinkopiert werden. Sobald man nun das NETBroker.LegacyCode Projekt erneut baut, sollte es keinen Fehler mehr geben. Nun hat man aber im C++ Projekt dafür vier neue Dateien:

  • NETBroker.LegacyCode.h
  • NETBroker.LegacyCode_i.c
  • NETBroker.LegacyCode_p.c
  • Dlldata.c

Diese 4 Dateien muss man nun noch in das C++ Projekt einfügen und damit ist der Code-Teil im C++ Reich bereits abgeschlossen – aber Achtung compilieren funktioniert noch nicht. Der Konfigurationsspaß fängt erst an. Nun benötigen wir noch eine DEF-Datei im C++ Projekt, das bedeutet im Projekt erst noch per Rechtsklick eine DEF-Datei erzeugen, und in diese kommen folgende fünf Zeilen:

LIBRARY NETBroker.Proxy.dll

EXPORTS
   DllCanUnloadNow PRIVATE
   DllGetClassObject PRIVATE
   DllRegisterServer PRIVATE
   DllUnregisterServer PRIVATE

Anschließend, müssen im C++ Projekt noch folgende Einstellungen vorgenommen werden:

 


Danach sollte das Projekt compilieren, oder es wurde ein Fehler gemacht. Nun muss dafür gesorgt werden, dass die Proxy-DLL und die implementierte WINMD Datei (also die größere!) zusammen in einem Verzeichnis liegen, dass im späteren Verlauf von der App verwendet wird. Dafür habe ich mir folgendes Verzeichnis angelegt: C:\WindowsStoreApp. Dementsprechend empfiehlt es sich, beim C++ Projekt eine Projektabhängig einzutragen, und das C++ Projekt erhält auch ein POST-Build:

Dadurch liegen in diesem Verzeichnis immer die aktuellsten Dateien. Daraufhin müssen die Rechte des Verzeichnisses noch korrekt gesetzt werden, d.h. im Windows Explorer per Rechtsklick zur Sicherheit des Ordners.

 

Und zwar benötigen „ALLE ANWENDUNGSPAKETE“ Vollzugriff auf den Ordner damit diese darauf auch zugreifen können. Sobald dies geschehen ist, muss der Proxy nur noch registriert werden per regsvr32. Daher wird eine CMD-Shell (Administratorrechte!) aufgerufen werden, und in das Verzeichnis „C:\WindowsStoreApp“ gewechselt werden. Da erledigt der Befehl:

Regsvr32 NETBroker.Proxy.dll

… den Rest.

 

Dadurch benötigen wir nun nur noch unsere neue Windows 8.1 App, NETBroker.App und dieser können wir nun eine neue Referenz hinzufügen und zwar auf die reference-Winmd Datei (die kleinere!). Diese befindet sich im Ordner „NETBroker.LegacyCode\bin\x86\Debug\reference“. Eine kleine Änderung im Manifest (Package.appx) ist noch manuell zu tätigen, dafür muss diese mit einem Beliebigen Texteditor geöffnet werden (Notepad++ zum Beispiel).

Am Ende der Datei wird eine kleine „Extension“ benötigt die einerseits bekannt gibt, welche Klasse angefordert wird, und wo diese liegt (C:\WindowsStoreApp).

<Extensions>
<Extension Category="windows.activatableClass.inProcessServer">
<InProcessServer>
<Path>clrhost.dll</Path>
<ActivatableClass ActivatableClassId="NETBroker.LegacyCode.CustomerRepository" ThreadingModel="both">
<ActivatableClassAttribute Name="DesktopApplicationPath" Type="string" Value="C:\WindowsStoreApp" />
</ActivatableClass>
</InProcessServer>
</Extension>
</Extensions

Damit ist man nun bereits am Ende angelangt und kann in der Windows Store App, die Klasse CustomerRepository komplett „normal“ verwenden.

Und daraus wurde eine "einfache" App die ADO.NET (aber vollen Zugriff auf das .NET Framework) verwendet:

Das ganze basiert auf folgendem Paper von Microsoft: http://msdn.microsoft.com/en-us/library/windows/apps/dn630195.aspx sollte wer Fragen oder Tipps haben gern per Mail oder Twitter @giessweinweb. Download

 

UPDATE:

Nachdem ich mit Harry Pierson von Microsoft ein paar Mails ausgetauscht habe folgende Dinge noch:

  • You don’t need comvisible or guid attributes on the class
  • You don’t need to declare a separate comvisible interface on the class if you don’t want to. If you choose to, you don’t need the com visible attribute but you do still need the guid attribute
  • We have a template coming soon that should make all the manual project file hacking a thing of the past. 

Das heißt es ist auch hierbei etwas im Ofen bei Microsoft.

codefest.at [MS]: Entwickeln für Windows Phone 8.1

Gestern wurden die letzten Puzzlestücke freigegeben, um endlich Windows Phone 8.1 Apps bauen und veröffentlichen zu können.

Wir haben für euch diese hilfreiche Liste erstellt, damit ihr als Developer mit Windows Phone 8.1 richtig durchstarten könnt.

Tool

Um Windows Phone 8.1 Apps zu bauen, benötigt ihr Visual Studio 2013 Update 2 RC. Diese Visual Studio Update enthält unter anderem Untestützung für Windows Phone Silverlight Apps (8.0 und 8.1), Universal Apps (Windows Runtime, XAML) und Universal Apps mit HTML und JavaScript.

Device

Wenn ihr eure Windows Phone 8.1 Apps testen wollt, benötigt ihr klarerweise ein Windows Phone 8.1. Als Entwickler habt ihr nun die Möglichkeit, die Developer Preview für Windows 8.1 zu installieren. Ihr braucht dazu ein Developer Account oder eine Registrierung im Windows App Studio, installiert danach die App Preview for Developersauf euer Gerät, um beim Preview Programm mitzumachen und bekommt das Update dann normal über das Phone Update auf euer Gerät.

Store

Natürlich wollt ihr eure fertigen Apps auch gleich in den Store veröffentlichen. Seit gestern kann man im Windows Store auch Windows Phone Apps basierend auf der Windows Runtime im appx Format einreichen. Außerdem könnt ihr eure Windows Store und Windows Phone Apps miteinander verlinken.

HowTo

Nachdem ihr mit allem Nötigen gewappnet seid, könnt ihr gleich loslegen, die coolen Features von Windows Phone 8.1 in Apps einzubauen. Im Developer Center gibt es bereits eine neue Sektion , die ihr als Startpunkt verwenden könnt, um zu lernen, wie ihr neue Windows Phone Apps basierend auf der Windows Runtime schreibt.

Klaus Aschenbrenner: A ever-increasing Clustered Key value doesn’t scale!

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

You know all the best practices how to choose a Clustered Key value? A good Clustered Key value should have the following 3 properties:

  • Narrow
  • Static
  • Ever Increasing

Let’s have a more detailed look on all 3 properties, and why an ever increasing value doesn’t really scale in SQL Server.

Narrow

A Clustered Key value should be as small as possible. Why? Because it takes space, and the Clustered Key Value also serves a logical pointer in the leaf level in every Non-Clustered Index. If you have a very wide Clustered Key value, you also deal with larger Non-Clustered Indexes. If you have defined a Non-Unique Non-Clustered Index (which is normally the case), the Clustered Key value is also part of the navigation structure of your Non-Clustered Index. Therefore the overhead in your index gets very large. And our goal is to minimize overhead on our index pages. Overhead that we have to pay in the physical storage, and also in the Buffer Pool, where SQL Server caches the read index pages from storage.

Normally you choose a technical key value (like INT/BIGINT data type) instead of a natural key value. I have already seen over the years Clustered Key value lengths of 100 bytes and more (combinations of LastName, FirstName, SocialSecurityNumber, etc.). Believe me – you are just waisting memory! You don’t have to do that. Choose a technical key, and you are fine.

Static

Because the Clustered Key value is replicated in every Non-Clustered Index, your Clustered Key value should never ever change! Otherwise SQL Server has to maintain transparently in your UPDATE Execution Plan EVERY Non-Clustered Index that you have defined on your table. You are again just introducing additional computing overhead that you don’t need. Use your CPU cycles for more other important stuff. As you know, natural key values can change (like a LastName column, when you get married).

A technical key value (like an INT IDENTITY) can’t change (by default). Therefore the logical pointer (in the form of the Clustered Key value) in all your Non-Clustered Indexes remains stable - without any need to change them – forever!

Ever Increasing

And the 3rd final important property of a “good” Clustered Key value is that the chosen column should give you ever-increasing values. Why? Because you are always adding additional records at the end of your Clustered Index, and therefore you are avoiding expensive Page Splits (regarding CPU cycles, and Transaction Log overhead) and Index Fragmentation. In 99% of all cases you will be fine with an ever-increasing value like an INT IDENTITY column, but there are some scenarios, where this approach can lead to serious scalability problems. Imagine you have a workload, where a lot of different users are inserting permanently into the same table with an ever-increasing Clustered Key value. Just think a second about about Logging/Auditing tables.

Let’s have a more detailed look on what happens internally in SQL Server, when you reading and writing pages in memory. When SQL Server accesses certain memory structures (like pages that are stored in the Buffer Pool), these memory accesses must be synchronized among multiple threads. You can’t write concurrently to the same page in memory. When a thread writes to a page, some other thread can’t read the page at the same time. In traditional concurrent programming you solve that problem with Mutexes - like a Critical Section. Certain code paths are just mutually exclusive. A Latch in SQL Server is almost the same as a Critical Section. And latches are used to synchronize threads/queries among each other. Every time when you read a page, the worker thread has to acquire a Shared Latch (SH), every time when you write a page, the worker thread has to acquire an Exclusive Latch (EX). And both latches are incompatible to each other.

When you now perform an INSERT statement, the worker thread exclusively latches the page where the INSERT statement occurs. In the mean time no one else can read and write from/to this page. With an ever-increasing Clustered Key value this approach doesn’t really scale, because you are just inserting your records at the end of your Clustered Index. Therefore your parallel threads/queries are contending about an Exclusive Latch on the same last page in your Clustered Index. As a side-effect SQL Server executes your INSERT statement serially – one INSERT after the next one. You have hit the famous Last Page Insert Latch Contention. Let’s have a look at the following picture.

Last Page Insert Latch Contention

With the best practice of an ever-increasing Clustered Key value you have a single hotspot at the end of your Clustered Key. The smaller your records are, the more contention you are introducing here. How can you solve that problem? Easy: spread your INSERT statements across the whole B-Tree structure of the Clustered Index. There are various approaches how you can achieve that:

  • Use a random Clustered Key value (like a UNIQUEIDENTIFIER). But be aware of the side-effects: larger logical pointer in EVERY Non-Clustered Index, Page Splits…)
  • Implement Hash Partitioning, if you are using the Enterprise Edition of SQL Server.
  • Eliminate latching through the use of In-Memory OLTP, that is part of SQL Server 2014.
  • Use a so-called Reverse Index. Unfortunately SQL Server doesn’t provide you that kind of index out-of-the box, like Oracle. But you can implement it at your own

Summary

At 99% you will be fine with a narrow, static, and ever-increasing Clustered Key value like an INT IDENTITY data type. But in some rare scenarios where you need a huge amount of parallel INSERT statements (like Logging/Auditing tables), you can hit the Last Page Insert Latch Contention with that approach. If you hit that specific problem, you have to leave your comfort zone, and you have to make sure that you spread the INSERT statements across your whole B-Tree structure. You are mainly fighting against a limitation of how multi-threaded access happens in a traditional B-Tree structure.

I hope that I have given you with that blog posting a good insight, why ever-increasing Clustered Key values can hurt the scalability of your tables.

If you are more interested in how to choose the right Clustered Key Value, I’m also offering a 1-hour long training video through the SQLpassion Online Academy.

Thanks for reading!

-Klaus

Holger Sirtl: Azure-bezogene Nachlese zur BUILD-Konferenz

Gut 10 Tage ist die BUILD-Konferenz in San Francisco nun her. Neben all den Neuigkeiten zu Windows 8.1 und Windows Phone 8.1 sind die Erweiterungen und Innovationen in Microsoft Azure fast untergegangen. Ich möchte deshalb hier mal meine persönlichen Highlights zu Microsoft Azure zusammenfassen und mit entsprechenden Verweisen zu den jeweiligen Channel-9-Videos versehen:

Allgemeines im Bereich Microsoft Azure

Microsoft Azure war zentrales Thema in der Keynote des zweiten Konferenztags. Eine Reihe von Azure Services haben GA-Status erhalten. Dazu gehören das CDN, der Scheduler, die VPN Point-to-Site-Funktionalität und Visual Studio Online. In Mobile Services kann Anwendungslogik neben JavaScript nun auch in .NET implementiert werden. Der Notification Hub kann nun auch Kindle Mobile Push Notifications versenden. Für EA-Kunden kann das Active Directory nun auch in einer Premium-Edition genutzt werden. Mit Resource Groups lassen sich Umgebungen, die aus mehreren Azure Services (z.B. Website, Storage Account und CDN) bestehen, automatisiert einrichten und verwalten.

Darüber hinaus wurde die neue Portaloberfläche vorgestellt, die nun auch Details zu Rechnungen und Ressourcenverbrauch (insb. im Kontext von Abonnements) auflistet.

http://channel9.msdn.com/Events/Build/2014/KEY02
http://channel9.msdn.com/Events/Build/2014/2-607 (Resource Groups)

Microsoft Azure Compute

Was die Ausführung von Anwendungen auf Microsoft Azure betrifft, so betrafen die Neuerungen neue Instanzgrößen sowie neue Instanzklassen. Das bisherige Modell, bei dem VM-Instanzen eines Cloud Service hinter einem Loadbalancer und mit Auto-Scaling-Fähigkeiten versehen sind, wird nun als „Standard“-Modell bezeichnet. Hinzugekommen ist ein weiteres Modell: „Basic“. Bei diesem fehlen der Loadbalancer und die Möglichkeit zur Autoskalierung. Dafür liegen die Preise für „Basic“ ca. 27% unterhalb des „Standard“-Modells. Das „Basic“-Modell eignet sich deshalb zum kostengünstigen Betrieb von Single-Instance-Installationen (z.B. für Dev-Test, Demos, …).

Über diese Neuerung hinaus wurden die Funktionen für die Auto-Skalierung und den Scheduler in General Availability (GA) Status gesetzt.

http://channel9.msdn.com/Events/Build/2014/3-620
http://channel9.msdn.com/Events/Build/2014/3-621

Microsoft Azure IaaS (Virtual Machines)

Im Bereich VM-Management war die wichtigste Bekanntmachung die Kooperation mit Puppet Labs und Chef. Die Verwaltbarkeit von Virtual Machines rückt damit noch näher an die Verwaltbarkeit von Cloud Services, die ja von je her von hoher Automatisierung und minimalem Management-Aufwand punkten. „Puppet Enterprise“ vereinfacht die Bereitstellung vorgefertigter VMs und deren Bestückung mit Software-Paketen.

Darüber hinaus wurde Auto-Scaling in den GA-Status gesetzt. Darüber hinaus werden jetzt statische interne IP-Adressen unterstützt.

Im Zusammenspiel mit Visual Studio haben sich weitere Neuerungen ergeben. Es ist aus Microsoft Entwicklungsumgebung jetzt möglich auf viele Management-Funktionen, die bisher über das Azure-Portal zugänglich waren, zuzugreifen. Dazu gehören die Erstellung und Überwachung von VM-Instanzen. Zusätzlich ist es jetzt sehr einfach, aus Visual Studio heraus Anwendungen, die auf VMs in Azure ausgeführt werden zu debuggen.

http://channel9.msdn.com/Events/Build/2014/3-614
http://channel9.msdn.com/Events/Build/2014/2-658 (Puppet)

Microsoft Azure Websites

Auch bei Websites gab es zahlreiche Neuerungen: der Traffic Manager kann nun auch im Zusammenspiel mit Websites genutzt werden, Webjobs erlauben die Ausführung von Hintergrundprozessen in Websites, Auto-Skalierung ist nun allgemein Verfügbar (GA). Wie bei Cloud Services können nun auch bei Websites Staging Umgebungen genutzt und via VIP Swap mit Produktivumgebungen getauscht werden. Darüber hinaus können nun zeitlich geplante Backups erstellt werden.

Sehr wichtige Neuerung ist die Tatsache, dass nun auch Java als Entwicklungsplattform in Websites genutzt werden kann.

http://channel9.msdn.com/Events/Build/2014/3-624
http://channel9.msdn.com/Events/Build/2014/3-625
http://channel9.msdn.com/Events/Build/2014/3-626

Microsoft Azure Storage

Neben einigen Preissenkungen wurden zwei neue Redundanztypen für die Speicherung von Daten eingeführt: Zu den bereits bisher verfügbaren Redundanztypen (LRS = lokal-redundanter Speicher = 3 Kopien in einem Rechenzentrum, GRS = geo-redundanter Speicher = LRS + 3 Kopien in einem entfernten Rechenzentrum ohne Lesezugriff) kommen zwei neue Typen hinzu: RA-GRS (= Read-access geo-redundant storage), bei dem im Gegensatz zum einfachen GRS Lesezugriff auf die Daten im entfernten Rechenzentrum möglich ist, und ZRS (= zone redundant storage), bei dem die 3 Kopien auf 3 Rechenzentren innerhalb einer Region verteilt werden.

Darüber hinaus wurde das Speicherlimit pro Account auf 200 Terabyte erhöht und die Import/Export-Services in GA-Status gesetzt.

http://msdn.microsoft.com/library/azure/dn249410.aspx
http://azure.microsoft.com/en-us/pricing/details/storage/
http://channel9.msdn.com/Events/Build/2014/3-628

Microsoft Azure HDInsight

HDInsight ist Microsofts Hadoop-basierte BigData-Lösung für Microsoft Azure. Ab sofort werden hier auch Hadoop 2.2, .NET 4.5 und YARN (yet another resource negotiator) unterstützt. Es kann auf Audit und Betriebslogs zugegriffen werden. Des weiteren wurde Hive erweitert.

http://channel9.msdn.com/Events/Build/2014/3-612
http://channel9.msdn.com/Events/Build/2014/3-613

Microsoft Azure SQL Database

Der Datenbankdienst in Microsoft Azure hat eine neue Backup-Funktion erhalten, mit dem sich alte Versionen (max. 35 Tage) einer Datenbank wiederherstellen lassen. Zusätzlich ist es möglich, Geo-Replikation (mit bis zu vier aktiven, lesbaren Sekundär-Datenbanken) zu nutzen. Die garantierte Verfügbarkeit wurde auf 99,95% und die maximale Datenbankgröße auf 500 Gigabyte erhöht. Mit P3 gibt es in der Premium-Edition eine neue Größenklasse.

http://channel9.msdn.com/Events/Build/2014/3-630

Microsoft Azure Media Services

Für die Media Services hat es eine Reihe von Erweiterungen gegeben: MPEG-DASH für das On-demand-Streaming hat GA-Status erhalten, im Bereich HLS wird neben der bisher schon verfügbaren v4 nun auch v3 unterstützt, ebenso ist Dolby Digital Plus Unterstützung und MPEG-DASH für das OSMF Plugin für Smooth Streaming hinzugekommen. Als Preview ist Secure Delivery (PlayReady DRM oder AES 128), ein Office 365 Videoportal und MPEG-DASH Live Streaming verfügbar.

http://channel9.msdn.com/Events/Build/2014/3-610
http://channel9.msdn.com/Events/Build/2014/2-611

Weitere Informationen

ppedv Team Blog: TSQL - Der bessere Replace

Ab und zu sieht man den Wald vor lauter Bäumen nicht. Dieses Mal stand ich vor der Aufgabe aus einer Spalte bestimmte Werte zu ersetzen. Die Liste der zu ersetzenden Werte war doch etwas länger. Mit einem simplen Replace komme ich nicht besonders weit, da sich ja nur ein Wert ersetzen lässt.  Grübel grübel.. Doch es ist ganz simpel.

Das Prinzip:

Wir weisen einer Variablen einen per Replace bereinigten Wert zu.  Anschliessend wird auf das Ergebnis wiederum ein weiterer Replace angewendet (mit einem anderen zu ersetzenden Wert) und dann wiederum der Variable zugewiesen. Das machen wir solange bis wir alle zu ersetzenden Werte durch haben.  Das geht pfeilschnell.

Das ganze packen wir noch in eine Funktion und schon haben wir einen besseren Replace:

CREATE FUNCTION  dbo.BetterReplace (@str NVARCHAR(4000))
RETURNS nVARCHAR(4000) AS
BEGIN
    SET @str = REPLACE (@str,'>',' ')
    SET @str = REPLACE (@str,';',' ')
    SET @str = REPLACE (@str,'&',' ')
    SET @str = REPLACE (@str,':',' ')
    SET @str = REPLACE (@str,'<',' ')
    SET @str = REPLACE (@str,'/',' ')
    SET @str = REPLACE (@str,'\',' ')
    SET @str = REPLACE (@str,',',' ')
    SET @str = REPLACE (@str,'*',' ')
    SET @str = REPLACE (@str,'^',' ')
    SET @str = REPLACE (@str,'ü','ue')
    SET @str = REPLACE (@str,'ä','ae')
    SET @str = REPLACE (@str,'ö','oe')
    SET @str = REPLACE (@str,'"',' ')

  RETURN @str    
END

Zum Beispiel:

declare @str as varchar(100)
set @str='<Tel>+49\8677-98890'

select dbo.BetterReplace (@str)

Ergebnis:

Tel +49 8677-98890

Einfach und wirkungsvoll!

Fabian Deitelhoff: Thunderbird 24: verschlüsseln mit enigmail 1.6

E-Mail-Verschlüsselung mit enigmail 1.6Anfang August 2013 habe ich einen Blogpost zum Verschlüsseln mit Outlook 2013 und dem Outlook Privacy Plugin geschrieben. Verschlüsseln finde ich immer noch wichtig. Vielleicht sogar noch wichtiger als damals!? Ich bin mir gar nicht so sicher ob die Themen, die in den vergangenen Monaten in den Medien präsent waren, meine Einstellung eher verstärkt als aufgeweicht haben. Irgendwann besteht die Gefahr, dass sich eine große Portion Resignation breit macht. Am Konzept der verschlüsselten E-Mail möchte ich zunächst trotzdem festhalten, auch wenn es natürlich nur ein Tropfen auf den heißen Stein bedeutet. Da der Aufwand sehr gering ist und die Erweiterungen sehr transparent sind, stören sie auch nicht bei der täglichen Arbeit.

Dieses Mal geht es aber nicht um Outlook 2013 oder eine andere Version. Das Thema wird mittlerweile ausführlich im Blog behandelt, da ich inzwischen zwei weitere Blogposts zum Thema geschrieben habe. In diesem Beitrag geht es um den beliebten E-Mail Client Thunderbird und das Add-on enigmail, das für Thunderbird verfügbar ist.

Installation von enigmail

Die Installation von enigmail ist sehr einfach. Anders als bei Outlook 2013 muss das Add-on nicht manuell heruntergeladen und ein Installationsprogramm gestartet werden. Thunderbird besitzt, wie vielleicht schon von Firefox bekannt ist, ein eingebautes Add-on-System. Abbildung 1 zeigt einen Ausschnitt aus Thunderbird 24.4.0. Die Add-ons befinden sich hinter dem Menüpunkt “Extras” | “Add-Ons”. Die Registerkarte “Erweiterungen” listet alle bereits installierten Add-ons auf. Daher stammt auch der Screenshot aus Abbildung 1. Wenn enigmail noch nicht installiert ist, einfach auf “Add-ons suchen” klicken und enigmail oben rechts in das Suchfeld eingeben. Jetzt nur noch die gefundene Erweiterungen auswählen und installieren. Der Rest geschieht komplett automatisch.

Abb. 1: Installation von enigmail als Erweiterung über Thunderbird.

Abb. 1: Installation von enigmail als Erweiterung über Thunderbird.

Darüberhinaus bietet dieses Add-on-System noch den Vorteil, dass es sich automatisch um Aktualisierungen der bereits installierten Add-ons kümmert.

Konfiguration

Die Konfiguration von enigmail übernimmt ein gut gestalteter Assistent. Es besteht zwar auch die Möglichkeit, alle Einstellungen manuell vorzunehmen, allerdings bietet der Assistent alles notwendig an, damit enigmail direkt einsatzbereit ist. Die folgende Galerie enthält die sechs Schritte, die zur Konfiguration notwendig sind. Es werden E-Mail Adressen, das gewünschte Standardverhalten zu Signaturen und Verschlüsselungen und der PGP-Schlüssel abgefragt. Alles in allem keine große Sache, was enigmail sehr einfach und komfortabel macht.

Abb. 2: Konfiguration über einen Assistenten. Abb. 3: Auswahl der E-Mail Adressen beziehungsweise Konten. Abb. 4: Alle ausgehenden Nachrichten unterschreiben. Abb. 5: Ausgehende E-Mails manuell verschlüsseln. Abb. 6: Weitere Einstellungen beziehungsweise Verbesserungen. Abb. 7: Kompatibilitätseinstellungen für OpenPGP. Abb. 8: Auswahl eines bereits vorhandenen PGP-Schlüssels. Abb. 9: Zusammenfassung der Einstellungen.

Die Entscheidungen, die getroffen werden müssen, sind größtenteils selbsterklärend. Am Anfang wird – in Abbildung 2 – zunächst nur abgefragt, ob die Einstellungen mit dem Assistenten oder doch lieber manuell durchgeführt werden sollen. Abbildungen 3 bis 5 kümmern sich anschließend um Optionen, die direkt das Verschlüsseln und Entschlüsseln von Nachrichten betreffen. Erst müssen die E-Mail Adressen ausgewählt werden, für die enigmail konfiguriert werden soll. Ich hatte mich für zwei entschieden. Die anderen beiden nutze ich eher sporadisch. Anschließend habe ich eingestellt, dass zwar alle ausgehenden Nachrichten unterschrieben werden sollen, ich aber die Verschlüsselung einer Nachricht manuell auswähle. Für den ersten Test fand ich diese Variante besser.

Abbildungen 6 und 7 enthalten einige Einstellungen beziehungsweise Verbesserungen für die Kompatibilität mit OpenPGP. Wie wichtig die einzelnen Optionen sind, kann ich aktuell gar nicht sagen. Ich habe sie bei den Standardwerten belassen und im Moment keine Probleme.

Die vorletzte Abbildung 8 erlaubt die Auswahl eines bereits vorhandenen PGP-Schlüssels oder die Generierung eines neuen. Da ich schon einen Schlüssel hatte, habe ich diesen ausgewählt, was ohne Probleme funktionierte. Zu guter letzt zeigt Abbildung 9 eine Zusammenfassung aller im Assistenten vorgenommenen Änderungen, die Bestätigt werden müssen. Alternativ kann auch zu den vorherigen Einstellungen zurückgesprungen werden, um Änderungen vorzunehmen.

Damit ist die Konfiguration von enigmail abgeschlossen und das Add-on ist einsatzbereit. Alles in allem müssen einige Einstellungen mehr getroffen werden, als das beim Outlook Privacy Plugin 2.0 der Fall war. Kommt mir zumindest durch den Assistenten so vor. Ebendieser Assistent sorgt aber auch dafür, dass nicht ständig zwischen verschiedenen Dialogen oder gar Programmen gewechselt werden muss und dass alles in schön geordneter Reihenfolge abgefragt wird.

Ver- und entschlüsseln

Abb. 10: Optionen für eine Nachricht.

Abb. 10: Optionen für eine Nachricht.

Nun fehlt nur noch ein kleiner Test der Konfiguration. Beim Schreiben einer neuen E-Mail befindet sich in der Menüleiste ein neuer Eintrag Namens “OpenPGP”, über den die Einstellungen zum Unterschreiben und Verschlüsseln von E-Mails erreichbar sind (siehe Abbildung 10).

Die ersten beiden Einträge können angeklickt und so aktiviert werden, was aber noch nicht zur Abfrage des Passworts für den PGP-Schlüsseln führt. Stattdessen kann erst die E-Mail zu Ende geschrieben beziehungsweise direkt verschickt werden, wenn sie schon vollständig war.

Erst beim Verschicken der Nachricht fragt OpenPGP – nach einer kurzen Verzögerung – das Passwort für den Schlüssel ab, wie Abbildung 11 zeigt. In diesem Fenster wird auch ganz klar angezeigt, um welche Absender-Adresse es sich handelt. Auch einige Informationen zum Schlüssel sind enthalten. Wird der Dialog mit OK bestätigt, verschlüsselt enigmail die E-Mail und verschickt sie anschließend.

Abb. 11: Verschlüsseln einer E-Mail.

Abb. 11: Verschlüsseln einer E-Mail.

Das war es im Grunde auch schon. Trifft eine verschlüsselte E-Mail ein und wird geöffnet, fragt enigmail automatisch nach dem Passwort für den PGP-Schlüssel. Nachdem die E-Mail entschlüsselt ist, zeigt enigmail im oberen Bereich der E-Mail den Status einer Prüfung an. Also ob es sich um eine entschlüsselte E-Mail handelt und ob eine eventuell vorhandene Unterschrift korrekt ist. Abbildung 12 zeigt einen kleinen Ausschnitt aus einem Screenshot.

Abb. 12: Status einer geöffneten E-Mail.

Abb. 12: Status einer geöffneten E-Mail.

Das eingegebene Passwort wird von enigmail im Übrigen für 10 Minuten gespeichert. So lange kann eine geöffneten und entschlüsselte E-Mail gelesen werden. Nach dem Ablauf der Zeit wird das Passwort erneut abgefragt und im Hintergrund die verschlüsselte Nachricht angezeigt, bis das korrekte Passwort eingegeben wurde. Diese Prüfung verhindert, dass eine einmal entschlüsselte Nachricht nicht auch nach etlichen Stunden noch entschlüsselt vorliegt und eingesehen werden kann.

Fazit

Mit enigmail steht ein mächtiges Add-on für den E-Mail Client Thunderbird zur Verfügung, der häufig eine echte Alternative zu Outlook ist. Das Add-on erledigt seine Aufgabe schnell, zuverlässig und ohne zu sehr beim E-Mail Schreiben in den Workflow einzugreifen. Kurz gesagt: es stört im täglichen Ablauf kein bisschen. Zudem ist es Open Source und schon einige Jahre im Einsatz. Neben den hier beschriebenen Funktionen gibt es noch zahlreiche weitere.

Von meiner Seite aus gibt es daher eine klare Empfehlung an alle Nutzer von Thunderbird.

Sven Hubert: DevOps und Continuous Delivery: sich gemeinsam kontinuierlich verbessern

Softwareentwicklung ist Teamarbeit. Die sich immer mehr verbreitenden agilen Vorgehensmodelle sind das beste Beispiel dafür. Dabei wird beispielsweise ein Sprint bzw. eine Iteration gemeinsam geplant, sich täglich über den Fortschritt ausgetauscht und abschließend gemeinsam reflektiert. Am Ende des Sprints steht ein Softwareprodukt zur Verfügung, welches neue Features und Verbesserungen enthält und von den Kunden genutzt werden kann. Soweit die Theorie. Häufig ist die automatische Auslieferung neuer Softwareversionen mit dem Kopieren der Ergebnisse eines zentralen Server Builds auf ein Netzlaufwerk oder einen Webserver für Entwicklungsabteilungen beendet. Bis dahin ist diese Vorgehensweise als Continuous Integration in vielen Entwicklungsteams implementiert. Danach sind oft diverse manuelle Schritte notwendig, um anschließend die Qualitätssicherung durchführen zu können, welche die Codeänderungen mit manuellen und automatischen Tests auf unterschiedlichen Systemen und Umgebungen verifiziert.

Continuous Delivery erweitert Continuous Integration um diese bisher zu wenig beachteten Aktivitäten. Neben diesen vorwiegend technischen Aspekten wird die notwendige Kommunikation zwischen Entwicklungsabteilungen und IT-Administration bzw. Konfigurationsmanagement allzu oft vernachlässigt oder findet überhaupt nicht statt. Hierfür hat sich in den letzten Jahren unter dem Codenamen DevOps die gegenseitige Annäherung von Entwicklung und Betrieb etabliert, wodurch Continuous Delivery tatsächlich erst realisierbar wird.

Der Artikel im OBJEKTspektrum Online Themenspecial DevOps und Continuous Delivery arbeitet die wesentlichen Bestandteile von Continuous Delivery heraus, die damit einhergehende, notwendige Kooperation zwischen Entwicklung und Betrieb und gibt einen Überblick über die zur Realisierung notwendigen Schritte. Der Fokus liegt hierbei auf der konzeptionellen Ebene, technische Beispiele erfolgen unter Verwendung des Microsoft Team Foundation Servers.

Lesen Sie den kompletten Artikel hier.

DevOps und Continuous Delivery: sich gemeinsam kontinuierlich verbessern is a post from: AIT Blog

codefest.at [MS]: AppFlash 3/14

Wir haben wieder die neusten und interessantesten Apps für euch zusammengestellt. Es freut uns, euch heute viele Apps Made-in-Austria vorstellen zu dürfen, nämlich PULS 4, iTranslate, Music Maven und Poki.

windows-8-logo_thumb52

PULS 4 logo

PULS 4

Die brandneue PULS 4 Windows App bringt jetzt kostenlos, jederzeit und überall deine Lieblingssendung auf deinen Windows PC oder Tablet. Du hast deine Lieblingssendung von PULS 4 verpasst? Kein Problem! Ab jetzt kannst du deine gewünschte Sendung unabhängig vom aktuellen TV-Programm ansehen. Außerdem können aktuelle TV-Sendungen per Live-Stream mitverfolgt werden. Fußball-Fans aufgepasst: mit dem mobilen Live-Stream bleibst du immer am Ball und verpasst kein Tor der UEFA Champions League mehr.

 

iTranslate 

iTranslate ist ein wirklich gutes Übersetzungs-Tool, das dir dabei hilft, Sprachbarrieren zu überwinden. Durch iTranslate kannst du jede unterstützte Sprache in Sekundenschnelle übersetzen. iTranslate übersetzt Wörter, Phrasen und Texte in über 80 Sprachen. Ein witziges Feature ist, dass man auch zwischen unterschiedlichen Dialekten switchen kann und sich so z.B. die unterschiedliche spanische Aussprache von Spaniern und von Mexikanern anhören kann. iTranslate ist übrigens auch für Windows Phone verfügbar.

 

 

iTranslate

music maven logo 2

Music Maven

Music Maven ist ein eine lustige Musikrätsel-App, die von unserem Ex-DPE Intern Christian Vorhemus erstellt wurde. Bei Music Maven hörst du 130 bekannte Sounds und Musikstücke, deren Titel es zu erraten gilt.  Je mehr Level gelöst und freigeschaltet werden, desto mehr Punkte sammelt man, die gegen Hinweise eingetauscht werden können.

 

FIFA 14

Das Kult-Fußballspiel FIFA 14, das im letzten AppFlash bereits für Windows Phone vorgestellt wurde, ist inzwischen auch für Windows verfügbar.

FIFA 14
 
windows-phone-logo_thumb52
contre jour
QR-Intersport_thumb2

Contre Jour

Contre Jour ist definitiv ein einzigartiges und wahrscheinlich auch das originellste Windows Phone Spiel. Es ist im Windows Phone Store für 2,99 € erhältlich. Es stellt eine Mischung aus Spiel und interaktiver Kunst dar. Mit deinem Finger kannst du die Landschaft verwandeln, in der sich ein kleines geheimnisvolles Wesen bewegt. Tippe, ziehe und streiche auf diverse Vorrichtungen, um die niedliche Kreatur in Sicherheit zu bringen. Das besondere an Contre Jour ist die verzaubernde und originelle Musik, die dich während des Spielens begleitet und ganz konkret auf den Spielverlauf abgestimmt ist. Dank der intuitiven Steuerung kannst du die Welt um dich herum verändern – probier’s selbst mal aus und verlier dich in der Welt von Contre Jour. Ich selbst bin schon süchtig danach…


 

 
 

Poki

Poki ist eine der wenigen richtig tollen Apps, die nur für Windows Phone verfügbar sind. Bei dieser App handelt es sich um einen Pocket Client für Windows Phone mit einem einzigartigen Leseerlebnis. Der aus OÖ stammende Entwickler Tobias Klika konnte mit seiner App Premiere Poki bereits international Erfolge feiern. Seine App ist bereits in 164 Ländern verfügbar und wurde sogar beim heurigen Mobile World Congress in Barcelona präsentiert. Poki verfügt über einen Offline-Modus mit detaillierter Speicherübersicht, sodass du stets Artikel lesen kannst, auch wenn du keinen Internet-Zugang hast. Die Leseansicht lässt sich frei gestalten. Die Artikel können auch vorgelesen werden und die Lese- und Hörposition wird automatisch gespeichert. Artikel können nach Titel, URL oder Tags durchsucht werden. Poki ist ein Client für den Dienst Pocket. Immer wenn du auf einen interessanten Artikel, ein Video oder eine Website triffst, musst du dir nicht mehr umständlich einen Link senden, sondern legst ihn einfach bequem in Poket ab. Die App kostet 1,99 €, ist aber definitiv die Investition wert!

 

 

poki logo
QR - poki 








tap the frog logo
QR - tap the frog

Tap The Frog

Endlich gibt es dieses Spiel nun auch für Windows Phone! Das Spiel macht absolut süchtig und man kann gar nicht mehr die Finger vom Smartphone Screen lassen. Tap The Frog besteht aus einer Reihe von Mini-Games – in der Free-Version sind drei Spiele enthalten, in der kostenpflichtigen Version sind es elf. Mein absoluter Favorit ist das Spiel “Knall den Frosch”, das leider nur in der kostenpflichtigen Version verfügbar ist, der Mega-Spielspaß ist aber auf jeden Fall den kleinen Preis von 0,99 € wert. Die Versuchung bei diesem Min-Game ist einfach zu groß und man will sich stets selbst bzw. den Highscore von Freunden schlagen. Bei diesem Klassiker geht es darum, so viele Frösche wie möglich platzen zu lassen. Bei den drei Mini-Games, die in der Gratis-Version enthalten sind, hüpft man mit dem süßen Frosch auf Seerosen und versucht nicht ins Wasser zu fallen, man färbt Frösche um, sodass sie die gleiche Farbe haben oder man lässt den Frosch fliegen und bringt dabei Seifenblasen zum Platzen.

Hoffentlich waren wieder ein paar interessante Tipps für euch dabei. Viel Spaß beim Ausprobieren!

Thomas Bandt: C# async/await: Tasks und out-Parameter - eine Alternative

Ich bin ein Freund davon, Code so explizit wie möglich zu schreiben. Geht es beispielsweise um ein Repository, das mir in einer Methode einen Kommentar zurück gibt, möchte ich nicht im aufrufenden Code anschließend auf null prüfen müssen, weil ich mir unsicher bin, ob wirklich ein Kommentar zurückkommt, oder nicht doch null.

Dort, wo ein Crash an der Stelle okay ist, weil der Kommentar ganz sicher da ist, würde die Methode schlicht Single() lauten, dort, wo das nicht der Fall ist, immer TrySingle().

Im .NET-Framework hat sich dafür ein nettes Pattern etabliert:

public bool TrySingle(int id, out Comment) {}

Aufruf:

Comment comment;
if (!_repository.TrySingle(id, out comment))
{
	// Behandle den Fehler
}

Nun stelle ich gerade ein solches Repository auf async/await um, womit ich mit dieser Vorgehensweise ein klitzekleines Problem habe, denn dieser dafür notwendige Code kompiliert nicht:

public Task<bool> TrySingle(int id, out Comment) {}

Tasks dürfen keine Out-Parameter besitzen. Ohne Task aber auch kein async/await.

Eine Möglichkeit wäre die Verwendung eines Tuples, allerdings habe ich persönlich die Erfahrung gemacht, dass die in C# sehr, sehr schnell sehr, sehr hässlich werden. Vor allem hässlich zu lesen.

Eine Alternative ist ein eigener Datentyp, der als Boolean fungiert, womit sich die Nutzung nicht großartig verändert:

public class Maybe<T> where T : class
{
	public T Value { get; set; }

	public static implicit operator bool(Maybe<T> t)
	{
	    return t.Value != null;
	}
}

Die Repository-Methode schaut nun aus wie folgt:

public Task<Maybe<Comment>> TrySingle(int id) {}

Und ihr Aufruf:

Maybe<Comment> comment = await _repository.TrySingle(id);
if (!comment)
{
	// Behandle den Fehler
}

Ich habe die Umstellung gerade erst begonnen, es fühlt sich jedoch sehr angenehm in der Verwendung an.


| Kommentieren | © 2014 Thomas Bandt

Fabian Deitelhoff: Der Visual Studio-Style “Son of Obsidian”

Abb. 1.: Der Visual Studio-Style "Son of Obsidian".

Abb. 1.: Der Visual Studio-Style “Son of Obsidian”.

Neulich wurde ich gefragt, welchen Visual Studio-Style beziehungsweise welches Theme ich im Screenshot zur Dna-Klasse benutze. Damit ist eines der beiden Bilder im Header meines Blogs gemeint.

Gute Frage dachte ich mir :). Ich musste tatsächlich erst mal nachschauen, da ich mir nicht mehr ganz sicher war, wie das Farbschema hieß oder woher ich es hatte. Da es aber eine gute Anlaufstelle für Visual Studio-Styles gibt, dauerte die Suche nicht lange.

Das Schema benutze ich nämlich schon eine ganze Weile, da es mir sehr gut gefällt. Ich finde die Hervorhebungen deutlich besser als im Standard von Visual Studio. Vor allem bezogen auf Schlüsselwörter, Kommentare, Zeichenketten und eingebettete URLs. Natürlich ist das Geschmackssache. Egal welche Farben es am Ende sein sollen, wichtig finde ich, dass es den eigenen Vorlieben entspricht, da es das Arbeiten noch ein Stück angenehmer macht.

Das Farbschema heißt “Son of Obsidian” und lässt sich ganz einfach von studiostyl.es herunterladen. Dort stehen Versionen für Visual Studio 2005 bis 2013 und für WebMatrix 2 Beta zur Verfügung. Ausprobiert habe ich allerdings nur Visual Studio 2012 und 2013. Dort funktioniert es ohne Probleme. Einfach die Datei über den Menüpunkt “Tools” | “Import And Export Settings…” importieren. Abbildung 1 zeigt dazu einen Screenshot. Anschließend sind die Einstellungen aktiv und werden direkt angezeigt beziehungsweise für die geöffneten Dokumente verwendet. Auf studiostyl.es sind noch deutlich mehr vorgefertigte Farbeinstellungen für Visual Studio vorhanden. Über die Webseite können sogar eigene Farbkombinationen erstellt und als Style veröffentlicht werden.

Lediglich die Farbe für die Selektion von Text habe ich angepasst. Die war mir deutlich zu dunkel und unterschied sich kaum vom Hintergrund. Wie in Abbildung 2 zu sehen, habe ich ein leichtes Blau eingestellt. Das passt für mich deutlich besser. Ansonsten ist alles beim Standard geblieben.

Abb. 2: Beispiel für die Farbgebung in einer Konsolenanwendung.

Abb. 2: Beispiel für die Farbgebung in einer Konsolenanwendung.

ppedv Team Blog: Open Source: Plötzlich spielt es eine Rolle

Vor rund zwei Jahren habe ich hier im Blog eine Diskussion losgetreten. Völlig frustriert von der miesen Qualität diverser Bibliotheken und fehlender Dokumentation habe ich Dampf abgelassen. Die Aussage: “Es ist mir scheißegal, ob Open Source oder nicht.”

Im Bezug auf die aktuellen Geschehnisse um OPENSSL und den #heartbleed Bug muss ich meine Meinung revidieren. Es ist plötzlich wichtig #OPENSOURCEFREE auf das Produkt-Paket gedruckt zu bekommen. Um es klar zu sagen, dies war kein Einzelfall:

  • Heartbleed, unentdeckt für ca 2 Jahre, schlimmster Sicherheitsunfall in der Geschichte des Internets
  • GnuTLS blieb 10 Jahre unentdeckt
  • Eine fehlende Codezeile im Random Number Bug über 2 Jahre
  • TCP-32764 Backdoor, dessen Urheber bis heute unklar ist

Damit gilt das oft zitierte Statement als widerlegt. In der Wissenschaft reicht ein Negativbeweis. Die Diskussion über Open Source als Sicherheitsrisiko, speziell im Unternehmenseinsatz, ist über 10 Jahre alt, wird aber von den Verfechtern negiert.

"Weil aber Open Source die Offenlegung des Quellcodes bedeutet, können Anwendungen von allen Nutzern ständig weiterentwickelt werden. Auch Fehler lassen sich so meist schneller beheben."

"Der Vorteil von Open Source: Schadsoftware, Bugs oder Sicherheitslücken können in der Regel schneller entdeckt werden. Es reicht allein der Verdacht, und Tausende von EntwicklerInnen nehmen den betreffenden Code ganz genau unter die Lupe", sagt Grote. Die größere Gefahr bestehe vielmehr in den unfreien Komponenten, etwa proprietären Modemtreibern oder Firmware, die meist von den Herstellern kommen und deren Sicherheit niemand überprüfen kann."

Nun stehen zwei Konzepte gegenüber: Open Source und Closed Source. Warum ich glaube, dass Closed Source die bessere Wahl sein kann:

Kosten

Es wird argumentiert, dass bei Open Source die Lizenzkosten wegfallen. Das Beispiel der Stadt München hat bewiesen, dass man mit mehr finanziellem Aufwand ein qualitativ weniger hochwertiges Ergebnis erreichen kann - bei höherem zeitlichem Aufwand. Open Source kann nur seriös eingesetzt werden, wenn das Know-how und die Ressourcen vorhanden sind, den Code zu pflegen. Niemals kann man sich darauf verlassen, dass jemand für immer und gratis seine Bibliothek weiter pflegt oder das jemand ganz automatisch mit Freude und völlig unentgeltlich diesen Job übernimmt. Persönlich schmerzlich erfahren mit dotnetopenauth.

Sicherheit

Ganz generell gesprochen gibt es keinen schlüssigen Zusammenhang zwischen Sicherheit und Open Source. Ein Vier-Augen-Prinzip erhöht die Sicherheit in jedem Softwareprojekt, allerdings ist es auch ein Leichtes, in ein Open Source-Projekt Programmierer einzuschleusen, die andere Ziele verfolgen. Dabei hat sich gezeigt, dass die Entdeckung von Sicherheitslücken über Parsing Tools  und nicht per Code-Analyse erfolgte.

Verantwortung

Der letzte Punkt ist mir erst in den letzten Tagen so richtig klar geworden. Niemand übernimmt die Verantwortung. Gerade in einem Land wie Deutschland, in dem sich jeder gegen jedwede Risken versichert, in dem unglaublicher Aufwand getrieben wird den kleinsten Parksünder dingfest zu machen, kann es sich eigentlich niemand leisten, nicht zu wissen, wer eigentlich Schuld trägt.

Das ist sowohl rechtlich in Fragen der Gewährleistung als auch gesellschaftlich ein unhaltbarer Zustand.

Stellen Sie sich mal vor eine Airline würde Metallteile verbauen, die sie auf der Straße findet.  Dann hätten wir nicht nur eine MH370, sondern jeden Tag zehn. Verantwortungslos.

Fazit

Open Source wurde immer durch Gebrauch des englischen Begriffs "free" mit gratis verwechselt. Nachdem dieser Irrtum erwiesen ist und die erheblichen Risiken nicht mehr zu leugnen sind, müsste man folgerichtig ein EU-Verbot fordern. Oder zumindest abschreckende Warnaufdrucke, ähnlich der Zigarettenschachteln. Die werden auch nicht weniger schädlich, wenn man das billige Kraut raucht.

PS: Auch Microsoft hatte seine Sicherheitsgaus - bis vor etwa 10 Jahren (SQLSlammer), danach nicht mehr.

Jürgen Gutsch: LINQify the SimpleObjectStore

in den letzten Wochen habe ich weiter am SimpleObjectStore geschraubt. Mir ging es in der Zeit vor allem Darum die API zu vereinfachen und direkter Nutzbar zu machen. So habe ich mir ausnahmsweise mal das Entity Framework zum Vorbild genommen und analog zum DbSet das IObjectStore<T> LINQifiziert ;)

Wie das?

Eigentlich recht einfach. Der SimpleObjectStore basiert auf eine im Arbeitsspeicher gehaltene Liste. Diese ist die Grundlage für alle Operationen die mit dem ObjectStore möglich sind. Ich habe also Das Interface IObjectStore<T> um das Interface IEnumerable<t> erweitert. Der Enumerator ist der aus der zugrundeliegenden Liste. Dadurch ist der ObjectStore etwas einfacher nutzbar.

Mehrere Objekte selektieren:

using (var store = ObjectStore.GetInstance<MyEntity>())
{
    var actual = store.Where(x => x.Length > 50);
}

Hinzufügen eines einzelnen Objektes (AddOrUpdateRange() um mehrere Objekte hinzuzufügen):

using (var context = ObjectStore.GetInstance<InsertEntity>())
{
    context.AddOrUpdate(new MyEntity
    {
        Id = 11,
        Length = 11,
        Name = "Name11",
        Price = 11
    });
}<span style="font-size:10pt;">
 

Einzelnes Objekt selektieren:

using (var store = ObjectStore.GetInstance<MyEntity>())
{
    var actual = store.First(x => x.Id == 3);
}

Existierende Objekte abfragen:

using (var store = ObjectStore.GetInstance<MyEntity>())
{
    var result = store.Any(x => x.Name.StartsWith("Name"));
}

Spezielle Objekte löschen:

using (var context = ObjectStore.GetInstance<MyEntity>())
{
    context.Remove(x => x.Id <= 5);
}

Alle Objekte löschen:

using (var context = ObjectStore.GetInstance<MyEntity>())
{
    context.Clear();
}

LINQ Aggregat-Funktionen nutzen:

using (var store = ObjectStore.GetInstance<MyEntity>())
{
    var result = store.Sum(x => x.Price);
}

Was somit wegfällt ist der Aufruf von LoadAll() um erst Mal an die Liste der Daten zu kommen. Es kann nun also auch direkt über den Instanz eines konkreten IObjectStore<T> iteriert werden.

Dahinter steckt jetzt allerdings keine besondere Magie oder komplexe Logik, wie man vielleicht vermuten könnte, sondern der Zugriff auf die Interne Liste ist nun direkt über den Enumerator möglich, den ich nach Außen freigebe. Es geht hier also nicht um einen LINQ-Provider, wie er beim EntityFramework oder bei NHibernate existiert.

Dank Laurin Stoll (der mit mir zusammen beim einem Kunden einen Workshop zum Thema ASP.NET MVC und Entity Framework gemacht hat) habe ich einen sehr guten Einblick in die Aktuelle API des Entity Framework bekommen und konnte das Prinzip hier stellenweise umsetzen.

Was für einen Sinn hat das?

Der SimpleObjectStore ist keine vollwertige Datenbank und soll es auch nicht sein. Ziel dieses Tools ist es schnell Tests, Demos, Mockups und Click-Dummies aufzubauen, ohne sich um die Details der Persistierung kümmern zu müssen. Auch wäre es möglich UI-Driven zu entwickeln einfache Persistierungen umzusetzen. (HINWEIS: Für den Poduktiveinsatz unter Stress und in Multithreading-, bzw. Multiuser-Umgebungen wird dieses Werkzeug nur bedingt funktionieren)

Der Umstieg zu einer produktiv nutzbaren Persistierung sollte so unkompliziert wie möglich sein, ohne zu viel umstellen zu müssen. Die Direkte Nutzung von LINQ sollte das nun vereinfachen

Was wird noch kommen?

IEntity soll verschwinden. Ich möchte einfache POCOs verwenden können, statt die Implementierung von IEntity vorzuschreiben. in früheren Versionen war das eine einfache Möglichkeit um an den Identifier zu kommen. Schon jetzt kann aber Entweder das Identifier-Attribut verwendet werden oder ToString wird genutzt um Entitäten zu vergleichen. Eine zusätzliche Id-Konvention wäre ebenfalls denkbar.

Die aktuellen Änderungen sind im SourceCode Repository auf BitBucket zu finden, allerdings noch nicht per NuGet verteilt.

Jürgen Gutsch: Event Sourced Applications

Immer mehr bin ich davon überzeugt, dass überall dort wo in einer Applikation eine eindeutige Domäne ausgemacht werden kann, ein Event Source die richtige Datenhaltung ist.

Das mag für kleine Anwendungen etwas übertrieben sein, aber sobald diese kleine Anwendung wächst kann der Aufwand für diese Anpassung schnell unverhältnismäßig wachsen. Aktuell sitze ich auch an einem Projekt, das am Anfang recht einfach ausgesehen hat. Mit der Zeit, sind aber neue Anforderungen an der Kerndomäne hinzugekommen. Das Resultat sind unter anderem Sonderbehandlungen innerhalb dieser Domäne und die Komplexität der Software steigt annähernd exponentiell. Das ist unschön für den Entwickler der die neuen Anforderungen implementiert und für den der den Code warten muss.

Ein noch kommendes Reporting und Export der Daten muss nun ebenfalls auf diese Sonderbehandlungen reagieren. Die Komplexität habe ich also nicht nur bei der Erfassung der Daten, sondern auch beim Lesen der Daten.

Einfacher ist es die Daten in einem Event Stream abzulegen und gleich mehrere zusätzliche Features geschenkt bekommen:

  • Historie / Reporting
  • Logging / Protokollierung
  • Erweiterbarkeit / Evolvierbarkeit (auch auf die Datengrundlage)
  • Modularität
  • Stabilität

Event Source

Gemeint ist eine Art von Datenbank, in welcher die Aktionen auf ein Domainobjekt abgelegt werden. Das Domänenobjekt kann z. B. eine Kunde in einem CRM System sein. Jede Änderung einer Eigenschaft dieses Kunden wird nun persistiert: Die Änderung des Nachnamens, des Vornamens, der Adresse, etc. wird separat erfasst und abgelegt. Üblicherweise wird dabei für jedes Event die ID des Domänenobjekts (Kunden), die Reihenfolge der Events und das Erstelldatum des Events abgelegt, zuzüglich der geänderten Werte des Kunden.

Diese über die ID zusammenhängenden Änderungen, werden Event Stream genannt, das zugehörige Domänenobjekt ist das sog. Aggregate. Das Aggregate ist die Summe der zugehörigen Events. Soll heißen: Alle geladenen Events des Aggregates beschreiben dessen Zustand. Lade ich nur Events des Kunden bis vor zwei Wochen, habe ich den Zustand des Kunden von vor zwei Wochen (Historie).

Daraus ergeben sich die oben aufgelisteten Vorteile:

Historie

Alle Aktionen auf dem Zentralen Objekt werden als Events (und nur als Events) in der DB abgelegt, dadurch erhält man eine komplette Historie über alle vergangenen Aktionen. Das heißt auch, wir sind in der vergangene Zustände wiederherzustellen. Wir können sagen, wie die der Zustand eines Objektes vor zwei Wochen war. Dabei ist die Art des Objektes völlig irrelevant. Sei es ein Vertrag, ein Kunde, ein Werkstück, ein Dokument, was auch immer.

Logging

Wir sind in der Lage, nicht nur die Änderungen, sondern auch die Änderer und die Zeitpunkte der Änderungen mit anzugeben. Wir können also sehen, wer was zu welchem Zeitpunkt geändert hat. Praktisch die totale Überwachung auf Daten-Ebene.

Erweiterbarkeit

Dem Event Stream ist es egal, welche Events abgelegt werden. Kommen neue Anforderungen hinzu, so müssen nur neue Events definiert werden, die einfach zusätzlich in diesen Stream abgelegt werden. Das ist alles. Existieren die Events in der Vergangenheit nicht, sind sie für die Vergangenheit auch nicht relevant. Die Daten sind somit Modularisiert.

Modularität

Die Applikation wird bei neuen Anforderungen mit neuen Events ausgerüstet. Um auf diese Events zu reagieren, werden neue EventHandler angehängt. Es gibt weniger festen Abhängigkeiten in der Software. Auf eine Eventbasierte Datengrundlage kann auch einfach Eventbasiert Entwickelt werden.

Die Modularität geht noch einen Schritt weiter: Es können nicht nur neue Applikationsanforderungen über EventHandler implementiert werden, es können auch neue Datenextrakte – für Reportings, etc. – über EventHandler hinzugefügt werden. Ein Handler der auf Änderungen einer Kundenadresse reagiert, könnte die Daten über das Umzugsverhalten eines Kunden zu Statistikzwecken extrahieren.

Stabilität

Der EventStream sollte in einem stabilen System persistiert werden. Ist das gewährleistet ist auch für Datensicherheit gesorgt. Es gehen keine historischen Informationen verloren, da keine Events gelöscht werden, sondern immer nur neue hinzukommen. Daraus können Informationen für Statistiken, etc. immer wieder neu generiert werden.

Datenmigrationen bei einem Softwareupdate werden fast überflüssig gemacht. Auf veraltete Events muss nicht mehr reagiert werden. Neue Events beeinflussen alte Applikationen nicht. Nur auf die Struktur vorhandener Events muss ggf. geachtet werden. Je nachdem wie diese allerdings persistiert werden. kann auch das egal sein.

Und was ist mit CQRS?

Oftmals wird Event Source im Zusammenhang mit CQRS genannt. Es macht in vielen Fällen Sinn, dort wo das CQRS-Pattern genutzt wird, auch über Event Source nachzudenken. Umgekehrt macht es Sinn, dort wo die Event Source genutzt wird auch über CQRS nachzudenken. Da das Selektieren von Daten aus dem Event Stream recht aufwendig ist, sollte CQRS tatsächlich in Betracht gezogen werden. Also per EventHandler die Daten aus dem Events abzufangen und in eine separate, leseoptimierte Datenbank abzulegen. Also Quasi die aktuellen Zustände des Aggregates separat denormalisiert abzulegen und zu aktualisieren. Dadurch optimiert man die Lesezeit enorm.

Allerdings ist das kein Muss. Beide Patterns arbeiten hervorragend zusammen, müssen aber nicht zwingend in einen Zusammen eingesetzt werden.

Was meint Ihr?

Alexander Schmidt: Windows 8.1 Problemchen gelöst und einige nette Highlights

Nachdem ich mein Entwicklungssystem auf Windows 8.1 hochgezogen habe, nervten mich sogleich 2 Dinge. Ich habe jeweils eine Lösung gefunden möchte dies keinem codingfreaks-Leser vorenthalten. Zum Schluss zeige ich interessierten Lesern noch ein paar meiner Win 8.1 Update 1 Highlights. Problem Nummer 1: Windows Version unten rechts Ich habe zwar bereits ein ziemlich neues Motherboard […]

Thomas Bandt: iOS 7: "Corrupted Navigation Bar" mit Swipe-Back-Gesten

Apple hat mit iOS 7 "frei Haus" eine Gestensteuerung eingebaut, mit deren Hilfe der Nutzer über ein Wischen vom linken Rand einen zuvor geöffneten Dialog wieder schließen kann.

Voraussetzung hier ist, dass der Dialog nicht modal angezeigt, sondern auf den Stack des Navigation Controllers gepusht wird. Verwendet man eigene NavigationItems, braucht es etwas Nachhilfe, um die Funktion zu aktivieren, da der Standard-Back-Button nicht angezeigt wird, mit dem das Feature aktiviert wird:

InteractivePopGestureRecognizer.Delegate = new UIGestureRecognizerDelegate();
InteractivePopGestureRecognizer.Enabled = true;

Das Problem: verwendet man eben einen eigenen Back-Button oder schließt man Dialoge manuell, kommt es immer wieder zu Meldungen der Art "nested pop animation can result in corrupted navigation bar" und "Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.".

Apple formuliert das im Konjunktiv, tatsächlich ist es zu diesem Zeitpunkt meist schon zu spät:

Um das zu vermeiden, ist es notwendig vor dem Pushen den GestureRecognizer zu deaktivieren und ihn erst nach Beendigung wieder zu aktivieren, wie hier beschrieben.

Die Objective-C-Lösung findet sich in dem verlinkten Post, die MonoTouch-Variante folgt hier:

public class WSNavigationController : UINavigationController
{
    WSNavigationControllerDelegate _delegate;

    public WSNavigationController(UIViewController rootViewController) : base(rootViewController)
    {
        InteractivePopGestureRecognizer.Delegate = new UIGestureRecognizerDelegate();

        _delegate = new WSNavigationControllerDelegate();
        Delegate = _delegate;
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        _delegate.ViewControllerPushed += ViewControllerPushed;
    }

    public override void ViewDidDisappear(bool animated)
    {
        base.ViewDidDisappear(animated);

        _delegate.ViewControllerPushed -= ViewControllerPushed;
    }

    public override void PushViewController(UIViewController viewController, bool animated)
    {
        if (InteractivePopGestureRecognizer != null &&
            RespondsToSelector(new Selector("interactivePopGestureRecognizer")))
        {
            InteractivePopGestureRecognizer.Enabled = false;
        }

        base.PushViewController(viewController, animated);
    }

    private void ViewControllerPushed(object sender, EventArgs e)
    {
        if (InteractivePopGestureRecognizer != null &&
            RespondsToSelector(new Selector("interactivePopGestureRecognizer")))
        {
            InteractivePopGestureRecognizer.Enabled = true;
        }
    }

    public class WSNavigationControllerDelegate : UINavigationControllerDelegate
    {
        public event EventHandler ViewControllerPushed;

        public override void DidShowViewController(UINavigationController navigationController, UIViewController viewController, bool animated)
        {
            ViewControllerPushed(this, EventArgs.Empty);
        }
    }
}

Viel Spaß beim Wischen ;-).


| Kommentieren | © 2014 Thomas Bandt

ppedv Team Blog: Das April-Update für Windows 8.1 und Server 2012 R2

Zeitgleich mit dem Ende vom Support für Windows XP (und dem damit verbundenen letzten Patchday für eben dieses) veröffentlichte Microsoft am 8. April 2014 ein erstes größeres Update für Windows 8.1 und Windows Server 2012 R2:

http://support.microsoft.com/kb/2919355

Entgegen den Erwartungen bringt dieses Patch das "alte" Startmenü nicht zurück (dies soll mit einem weiteren Update vermutlich im Herbst nachgeliefert werden), hat aber dennoch einige Verbesserungen an Bord. Diese zielen vor allem darauf ab, die Bedienung mit Tastatur und Maus zu verbessern. Dazu gehören u.a. folgende Veränderungen:

  • Das System unterscheidet bei einigen Aktionen, ob diese mit der Maus oder dem Touchscreen ausgelöst wurden
  • Fährt man mit der Maus in einer geöffneten Modern UI App an den oberen Bildschirmrand, erscheint eine Box zum Minimieren und Schließen, so wie man es aus klassischen Fenster-Anwendungen kennt
  • Am unteren Bildschirmrand wird die Taskleiste eingeblendet
  • Ein Rechtsklick auf eine Kachel liefert diverse häufig genutzte Optionen
  • Verknüpfungen zu Modern UI Apps können auf der Taskleiste abgelegt werden
  • Auf der Startseite gibt es jetzt einen eigenen Button für den Shutdown, zusätzlich einen für die Suche

Neben diesen Änderungen werden eine ganze Reihe bekannter Probleme behoben. Welche genau kann man im TechNet KB Artikel nachlesen:

http://support.microsoft.com/kb/2919355/en-us

Das Update ist knapp 890MB groß und wird u.a. über Windows Update verteilt.

Code-Inside Blog: Fix: Cannot convert from ‘CConnectProxy::_ComMapClass *’ to ‘AddInDesignerObjects::IDTExtensibility2 *’

Mal einen etwas esoterischer Blogpost, welcher auftaucht wenn man zu viel mit Office Addins rumspielt. Der Fehler passiert beim Bauen von C++ Projekten, welchen diesen Typ benötigen.

Lösung (auf 64bit Systemen):

C:\Program Files (x86)\Common Files\DESIGNER>regsvr32 MSADDNDR.DLL

And Rebuild.

Meine lieben Kollegen hatte mir dies schon mehrfach gesagt, allerdings hatte ich es immer wieder vergessen :) Das Problem samt Lösung wird auch hier gezeigt.

codefest.at [MS]: Hands on Oculus Rift

Vor Kurzem wurde Oculus VR von Facebook um geschätzte 2 Milliarden US Dollar gekauft. Wir können nur hoffen, dass dies die Einführung ihres Vorzeigeproduktes, des Oculus Rift nicht verzögert oder gar behindert. Virtual Reality ist eines der großen Themen im IT und Gamingbereich, und daher möchten wir euch das Oculus Rift Development Kit vorstellen!

Das Development Kit kann für 350$ direkt bei Oculus VR bestellt werden. In der neuesten Version sollen OLED-Displays bereits für die nötig hohe Auflösung sorgen, wir mussten uns leider noch mit der älteren Version begnügen.

Das Development Kit selbst wird in einem hübschen und praktischen Koffer geliefert, der dafür sorgt, dass das Gerät auch auf Reisen unkompliziert mitgenommen werden kann. Enthalten ist die eigentliche Brille mit Kabelverbindung zum Mikrocontroller sowie ein Strom-, USB- und HDMI-Kabel für die Verbindung mit dem Computer. Fast schon ein wenig zu viel Kabelsalat für unseren Geschmack.

Das Rift ist fix per Kabel am Mikrocontroller befestigt

Die Installation ist in wenigen Schritten getan, Windows erkennt das Gerät bereits automatisch, komplizierte Einrichtung sowie Treibersuche bleiben einem erspart. Die Software für die Kalibration sowie offizielle Demoapplikationen sind unter https://developer.oculusvr.com (Registrierung notwendig) zum Download verfügbar. Wir empfehlen gleich vor dem ersten Start zusätzlich das RiftCoaster-Demo unter http://www.oculusriftenabled.com/RiftCoaster.html zu beziehen – in unseren Augen das beste Demo um sich selbst von den Qualitäten der Virtual Reality Brille zu überzeugen.

Brille auf, Demo starten und schon sitzt man mitten in einer Achterbahn, welche in einer mittelalterlichen Umgebung hochgezogen wird. Bereits hier macht sich erstes Gänsehaut-Feeling bemerkbar. Die 3D-Effekte, gepaart mit glaubhaftem Head-Tracking (welches komplette Rundumsicht in alle Richtungen erlaubt), überlisten sofort den Körper und es könnte einem richtig schlecht werden – was wir in dieser Hinsicht aber als Erfolg werten. Manch einer schloss sogar instinktiv die Augen in dem Moment, in dem sich der Achterbahnwaggon mit hoher Geschwindigkeit in Richtung Boden bewegt. Wir hätten stundenlang weiter dieselbe Runde fahren können, dazu ist es aber natürlich nicht gekommen, da bereits eine Menschenschlange hinter uns stand und das Ding sofort ausprobieren wollte.

Begeisterter Oculus Rift Tester

Nachdem wir einen halben Tag damit verbracht hatten, schwindelige und verwirrte Achterbahnfahrer aus dem Raum zu begleiten, nahmen wir das Gerät am Abend mit nach Hause, um uns die Integration in Games sowie Unity3D anzusehen.

Spielen selbst ist gar nicht so einfach, noch kaum ein Spiel unterstützt die Technologie aktiv. Bei vielen ist die Installation von Zusatzplugins von Nöten, uneingeschränkt können wir nur Half-Life 2 (VALVE) über Steam empfehlen. Hierfür muss man nur in den STEAM-Spieleigenschaften die Option „Beta-Tools“ aktivieren und sofort taucht ein neuer Hauptmenüpunkt auf um die Brille im Spiel zu aktivieren. Das Spiel läuft problemlos und sehr glaubhaft, hier möchte ich das Zielen mit der Maus unabhängig vom Head-Tracking positiv erwähnen. Auch wenn das Spiel und damit auch die Grafik bereits in die Jahre gekommen ist fiel uns vor Schreck mehrmals die Maus aus den Händen.

Und nun muss ich nach langem Honig-ums-Rift schmieren auch mit ersten Kritikpunkten kommen: Natürlich sieht man nichts mehr von seiner Umwelt und muss die Brille jedes mal Abnehmen um die Maus wieder zu finden. Ebenso erzeugt das längere Spielen leichte Kopfschmerzen (manche Testpersonen hielten keine Minute durch) und der Nacken sollte für exzessive Nutzung gut trainiert sein. Weiters ist zu hoffen, dass das finale Produkt kabellos funktioniert; fast hätten wir durch die Rundumsicht unsere Tastatur in Saft getränkt.

Doch nun zum nächsten wichtigen Punkt: Wie einfach ist es das Device in eigene Unit3D-Projekte zu integrieren? Unity3D kann unter https://unity3d.com/unity/download heruntergeladen werden, erlaubt Gameentwicklung mit C# auf hohem Niveau und punktet vor allem mit seinen multiplen Exportmöglichkeiten – ein Unity3D Projekt lässt sich für fast jede Plattform kompilieren – von Windows bis Linux, von Windows Phone bis IOs, von Xbox 360 bis Playstation. Einige dieser Features jedoch sind Besitzern der Pro-Version vorbehalten (PC-Betriebssysteme jedoch sind in der Free-Edition enthalten).

Unity beinhaltet außerdem den Code-Editor „MonoDevelop“ zum Bearbeiten der C# Scripts. Funktioniert an sich gut für kleine Übungen, wer jedoch Visual Studio gewohnt ist wird ob des geringen Funktionsumfangs etwas irritiert und enttäuscht sein. Glücklicherweise ist es kein Problem Unity3D in Kombination mit Visual Studio zu betreiben. Hierfür muss nur der Default-Code Editor in den Unity-Einstellungen auf Visual Studio geändert werden. Ab sofort wird beim Öffnen der Skripte Visual Studio als gewohnt komplexe Programmierumgebung gestartet. Details hierfür findet ihr unter: http://docs.unity3d.com/Documentation/Manual/VisualStudioIntegration.html.

Leider konnten wir Oculus Rift nicht ohne weiters in unser Unity-Projekt integrieren – nicht weil es kompliziert wäre sondern weil Unity das Feature unlängst aus der Free-Version entfernt und ausschließlich für die (1500 Euros teure) Pro-Variante zur Verfügung gestellt hat. Ein Fehler wie wir meinen, immerhin wird hierbei eine Vielzahl an nicht-kommerziellen Entwicklern aus dem Prozess ausgeschlossen. Laut Unity liegt dies vor allem an der Tatsache, dass um Rendern für Oculus Rift ein Pro-only PlugIn notwendig ist. Wir können einstweilen nur hoffen dass bereits ein kluger Kopf ein vergleichbares PlugIn für die Free-Edition entwickelt.

Fazit:

3D Applikationen für eine Reihe von Endgeräten zu entwickeln ging noch kaum so einfach wie mit Unity3D – und die perfekte Integration von Visual Studio ermöglicht dabei auch noch jenen Programmierkomfort den wir gewohnt sind. Das Oculus Rift ist ein cooles Device und wie wir meinen absolutes Muss für jeden Gaming-Freak. Um es jedoch mit unseren selbst-programmierten Demos verwenden zu können müssen wir jedoch noch ein wenig warten – sobald neue Möglichkeiten auftauchen das Device in die Free-Edition einzubinden werdet Ihr es auf CODEFEST.AT erfahren!

Norbert Eder: GNOME einfach erweitern

Seit nun längerer Zeit verwende ich Fedora mit GNOME. Ich freunde mich immer besser damit an. Man versucht sich eben aus unterschiedlichen Welten das Beste zu holen. Auch habe ich so eine gute (und sinnvolle) Nutzung für mein älteres Laptop gefunden, welches nun quasi als "Standrechner" fungiert. Im Laufe der Zeit fallen dann jedoch Problemstellen auf, die verbessert werden könnten, oder die gar etwas nervig sind und man beginnt sich auf zu Suche nach Lösungen zu begeben. Eine könnte in den GNOME Extensions liegen ...

Lars Keller: Here we go!–Microsoft MVP Award 2014

Ich bin zum sechsten Mal in Folge zum Microsoft MVP ernannt worden. Dieses Mal habe ich meine Expertise in Client Development gewechselt.

Sehr geehrte(r) Lars Keller,
herzlichen Glückwunsch! Wir freuen uns, Ihnen den Microsoft® MVP Award 2014 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 Client Development im vergangenen Jahr hoch ein.

Danke Community! Danke Microsoft!

Ralf Westphal: Wichtiges verlässlich erledigt kriegen

Erledigt wird nur, was dringend ist. Ich denke, darin stimmen wir überein. Aber es gibt Wichtiges und es gibt Dringendes. Beides muss erledigt werden – nur schiebt sich das Dringende scheinbar oft, allzu oft vor das Wichtige. Das Wichtige Das ist misslich und früher oder später gefährlich, denn das Wichtige ist ja das, was getan werden muss. Das macht seine Definition aus: Was bei Unterlassung

Johnny Graber: Code mittels NDepend analysieren

Um möglichst schnell in ein komplexeres Projekt einzusteigen hilft einem eine gute Übersicht. Visual Studio bietet je nach Ausgabe eine recht gute Code Analyse. Will man mehr wissen oder ist man an bestimmten Konstellationen im Code interessiert, stösst man aber schnell an Grenzen. Hier benötigt man einmal mehr die Werkzeuge und Ergänzungen von Drittherstellern.

Als ich vor einigen Wochen gebeten wurde mir NDepend anzuschauen kam mir dies sehr gelegen. NDepend ist ein Tool zur statischen Code Analyse für .Net. Damit lässt sich der Code nicht nur auf vorgefertigte Qualitätskriterien überprüfen, sondern man kann auch eigene Abfragen definieren.

 

Download und Installation

Auf NDepend.com kann man die Demo-Version als Zip herunterladen. Die Installation beschränkt sich aufs entpacken der Datei und einem Doppelklick auf die Installationsdatei.

Wenn einem die Möglichkeiten von NDepend gefallen bekommt man eine entsprechende Lizenz ab 299€. Leider gibt es keine GUI-basierende Möglichkeit um den Lizenzschlüssel einzugeben. Die Lizenzdatei muss man in den entpackten Ordner kopieren bevor man Visual Studio startet. Sonst wird nach Ablauf der Evaluationsperiode NDepend beim nächsten Start von Visual Studio deinstalliert.

Läuft NDepend genügt es das gewünschte Projekt in Visual Studio zu öffnen und über den Menüpunkt “NDepend” die Analyse zu starten. Dieser Vorgang ist zwar recht schnell, kann je nach Projektgrösse aber dennoch einige Minuten dauern.

 

HTML-Report

Das erste was einem als Resultat begegnet ist der HTML-Report. Dieser enthält die wichtigsten Punkte und soll als Zusammenfassung fürs Management dienen. Leider ist die Funktionalität äusserst beschränkt und damit einzig als Druckversion für die Gesamtsicht zu gebrauchen.

NDepend Report

 

Visual NDepend

Mit Visual NDepend hat man ein deutlich besseres Werkzeug zur Verfügung. Hier kann man die Grafiken genauer anschauen und auch einzelne Klassen auf der TreeMap finden. Klickt man auf Klassen- oder Methodennamen öffnet sich Visual Studio und zeigt einem die passende Stelle an.

Da alle Funktionen nur hier schön zusammengefasst werden dürften die meisten Benutzer vor allem mit Visual NDepend arbeiten. Man hat zwar immer noch den Wechsel zwischen Visual Studio und Visual NDepend, dafür kommt man aber sehr schnell zu den gewünschten Informationen.

Visual NDepend

 

Integration in Visual Studio

Die Integration in Visual Studio ist sehr gut und man kann mittels Rechtsklick auf eine Klasse die einzelnen Auswertungen direkt aufrufen. Bei der Gesamtübersicht wurde auf dem Dashbard allerdings nicht alles aus Visual NDepend übernommen. Es ist zwar alles in Untermenüs vorhanden, aber bis man die einzelnen Grafiken findet kann es dauern…

NDepend VS2013

 

Eigene Abfragen

NDepend glänzt vor allem durch die Abfragesprache CQLinq. Damit kann man selber den Code nach eigenen Kriterien durchsuchen (wie mehr als 4 Methoden mit mehr als 3 Parameter und mehr als 10 Attribute pro Klasse). Hat man gewisse Konstellationen entdeckt die häufig zu Problemen führen hilft einem CQLinq beim aufspüren.

Die Dokumentation zu CQLinq ist sehr ausführlich und sollte vor dem Experimentieren konsultiert werden. Die Hilfestellung bei Fehlern im Editor ist nicht gerade optimal und da die Abfragen immer gleich ausgeführt werden wird man sehr schnell mit Fehlermeldungen eingedeckt.

NDepend Query Editor

 

Verbesserungspotential

Die Inkonsistenzen der 3 Ansichten (HTML-Report, Visual NDepend und Visual Studio) sind nicht gerade Benutzerfreundlich. Hat man sich einmal daran gewöhnt kann man damit arbeiten. Allerdings ist es schade wenn man viel Zeit mit der Suche nach einer bestimmten Auswertung verliert nur weil sich diese in einem anderen Tool befindet.

Mit einer verständlicheren Kategorisierung der Fehler könnten die Reports auch dem Fachdienst bei der Beurteilung helfen. Code Climate schafft dies mit der Benotung A bis F für einzelne Klassen. Während ein A sehr gut ist gilt ein F als dringend zu verbessern. Zudem wird schön aufgezeigt wie sich der Code über die Zeit entwickelt, was einen zusätzlichen Motivationsschub gibt. Leider fehlen solche einfachen Werte bei NDepend, auch wenn Ansätze zum Verfolgen der Veränderungen vorhanden sind.

 

Fazit

NDepend ist ein tolles Tool für Entwickler die mehr über ihren Code wissen wollen. Um die Möglichkeiten voll auszuschöpfen wird man aber einiges an Zeit investieren müssen um selber CQLinq Abfragen zu erstellen.

Ausserhalb der Entwicklung sind die Einsatzmöglichkeiten von NDepend allerdings sehr beschränkt. Die Probleme bei der Benutzerführung und die Inkonsistenzen sind wie die Reports wenig hilfreich um mit dem Fachdienst über Qualitätsverbesserungen zu diskutieren.


Einsortiert unter:.Net, dnugBern, webDotNet Tagged: .Net, Clean Code, Tools

codefest.at [MS]: Das Smartphone Orchester–Nachlese zum Microsoft Day Vortrag

DeviceShot130412156693884330

Am Microsoft Day 2014 hatten die Teilnehmer die Möglichkeit, live unsere musikalischen Talente mit unserer NFC Orchestra App zu bewundern. Für alle, die nicht dabei sein konnten, gibt es diese Nachlese. Die Slides und das Recording der Session werden hier in den kommenden Tagen gepostet (Dieser Post wird dann aktualisiert).

In unserer Session “Das Smartphone Orchester – Lautstarker NFC Einsatz am Windows Phone” haben Andreas Jakl, der Entwickler der NDEF Library für Windows Phone, und ich euch gezeigt, wie ihr NFC Features in eure Apps einbauen könnt, und somit ermöglichen könnt, dass eure Apps mit der “echten” Welt interagieren können.

Die Demo-App, anhand der wir euch dies demonstriert haben, ist eine NFC Orchester-App, die bei Berührung von vorher vorbereiteten NFC Tags Instrumente bzw gesprochenen Text abspielt. So ist es möglich, die Tags auf den Tisch zu legen und mit dem Phone “DJ zu spielen”, um Musik abzuspielen.

Die Features, die wir euch in C# mit der NFC Library gezeigt haben, waren:

  • NFC Tags lesen
  • NFC Tags schreiben
  • Spracherkennung und –synthese
  • Peer-to-peer Kommunikation über NFC

Zu jedem Feature habt ihr auch Anwendungsgebiete aus dem Unternehmensumfeld erhalten, damit ihr seht, dass sich mit NFC auch sehr pragmatische Szenarien realisieren lassen.

Als besondere Weltpremiere haben wir euch gezeigt, wie ihr einen Viral Marketing Mechanismus in eurer App einbaut, damit die Benutzer motiviert sind, eure App ihren Freunden und Bekannten weiterzuempfehlen. Dazu haben wir ein Instrument gesperrt und ermöglichen dessen Entsperrung nur über NFC Peer-to-Peer Kommunikation. Wer also alle Instrumente haben will, benötigt eine zweite Person, die diese App installiert hat, damit beide das Instrument entsperren können.

Ihr könnt die App für Windows Phone 8 ab sofort aus dem Store herunterladen. Um die App verwenden zu können, benötigt ihr vorher aber 4 wiederbeschreibbare, formatierte NFC Tags. Hier könnt ihr zum Beispiel welche bestellen. Für die ersten Experimente mit NFC empfiehlt sich ein NFC Starter Pack - im Checkout-Prozess dann einfach Windows Phone angeben, damit die Tags bereits korrekt formatiert sind! Die Tags müsst ihr vorher noch mit den Instrumentinfos beschreiben. Dazu geht ihr in die Setup-Page in der App, klickt auf den “Schreib-Button” eines Instruments und berührt den NFC Tag mit dem Handy, um den Content auf den Tag zu schreiben. Sobald ihr die Tags beschrieben habt, könnt ihr die Instrumente abspielen.

Natürlich ist auch der Source Code der NFC Orchestra App auf CodePlex verfügbar. Die NDEF Library ist auch auf CodePlex und kann über NuGet ins eigene Projekt eingebaut werden. Im Übrigen gibt es zum Microsoft Day ein großes Update der NDEF Library, das viele neue Use-Cases mit NFC ermöglicht, zum Beispiel das Lesen und Schreiben von Visitenkarten, Kalender-Einträgen oder auch Bildern über NFC Tags. Am besten gleich die dazugehörige Demo-App mitsamt Source Code ausprobieren.

Have Fun Tapping!

Fabian Deitelhoff: Notizen: Kopf frei, Zettel voll

Leuchtturm1917 Notizbuch DIN A5Aufgaben zu verwalten ist schwer. Aufgaben im Kopf zu verwalten ist Blödsinn. Warum? Weil dabei garantiert etwas hinten runter fällt. Irgendetwas ist eh immer, wie es so schön heißt. Zu den alltäglichen Aufgaben kommt aber noch viel mehr. Ideen und kurze Geistesblitze zu aktuellen Problemen gehören für mich dazu. Und das sind nur einige Beispiele.

Schon lange organisiere ich diese Dinge über OneNote. Das funktioniert für mich sehr gut. Ich fand die Idee einer automatischen Synchronisierung gut. Zusätzlich stand OneNote auch irgendwann auf iOS-Geräte zur Verfügung. Mittlerweile ist es gar kostenfrei, was es für mich noch wertvoller macht.

Und doch fehlte etwas. Nicht selten beschrieb ich Blatt um Blatt von Collegeblöcken. Diesen Umstand wollte ich gerne ändern. Zumal es nervt, diese Zettelsammlung von einem Ort zum anderen zu transportieren. Das schreit förmlich danach, etwas zu vergessen. Dank Norbert Eder habe ich eine für mich passende Lösung gefunden.

Die Lösung ist so simpel, dass ich mich frage, warum ich nicht selbst darauf gekommen bin. Ich habe mir ein schönes Notizbuch gekauft. Für alle, die nicht mehr wissen was ein Notizbuch ist, habe ich einen Wikipedia-Link ergänzt :). Zur Auswahl standen verschiedene Formate von verschiedenen Herstellern. Bei den Formaten war für mich schnell klar, dass ich DIN A4 als deutlich zu groß empfand. DIN A5 stellte sich schnell als sehr passend heraus. Nicht zu klein, um kaum Notizen oder Zeichnungen unterbringen zu können und nicht zu groß, dass ich es nicht unkompliziert mitnehmen kann.

Moleskine vs. Leuchtturm1917

Bei den Herstellern war die Entscheidung nicht ganz so einfach. Die Auswahl konnte ich zwar schnell auf Moleskine und Leuchtturm1917 einschränken, aber die letztendliche Wahl war nicht ganz so einfach. Am Ende habe ich mich für Leuchtturm1917 entschieden. Die Gründe dafür waren:

  • Nummerierungen der 249 Seiten
  • Inhaltsverzeichnis auf den ersten drei Seiten
  • Sauber heraustrennbare Seiten hinten (acht Stück)
  • Falttasche im Einband
  • Titel- und Rückenschilder zur Beschriftung & Archivierung
  • Hardcover, das den Namen auch tatsächlich verdient
  • Neben Linienmuster und kariert auch gepunktet

Das hat mich schnell überzeugt. Auch die Kommentare bei Amazon gehen bei Moleskine immer mehr ins negative, da die Papierqualität abzunehmen scheint. Kann ich natürlich nicht beurteilen, war aber bei meiner Entscheidung das Zünglein an der Waage.

Bei den Seitennummerierungen und dem Inhaltsverzeichnis habe ich erst gestutzt und mich gefragt, wer das denn braucht. Jetzt weiß ich: wer es hat, wird es benutzen :). Kurz im Inhaltsverzeichnis eine Notiz, auf welcher Seite sich etwas befindet und eine mühsame Suche ist nicht mehr notwendig.

Entschieden habe ich mir zusätzlich für die gepunktete Variante, die ich als sehr angenehm empfinde. Die Punkte sind nicht so dominant wie ein Linienmuster oder die karierte Variante, helfen aber trotzdem beim Schreiben und vor allem bei Zeichnungen.

Fazit

Bis jetzt bin ich sehr begeistert. Die Seiten füllen sich langsam und die Zettelwirtschaft nimmt mehr und mehr ab. Natürlich ist es mit einem Notizbuch alleine nicht getan. Zu einer Ideensammlung gehört auch, sie regelmäßig durchzugehen, unwichtiges zu streichen und vor allem wichtiges zu digitalisieren. Denn im Endeffekt möchte ich gute Ideen oder sonstige Notizen immer noch digital haben, damit ich schnelleren Zugriff darauf habe und sie vielleicht auch einfach mal unkompliziert verschicken kann.

Dieses Feature fehlt den Leuchtturm1917-Notizbüchern leider noch :). Ansonsten sind sie für mich perfekt. Eine große Empfehlung meinerseits.

codefest.at [MS]: Visual Studio Tipps und Tricks MSDay2014

MSDN Vorteile und Hilfestellung beim Anfordern des Zugangs

Visual Studio 2013 Allgemeines

Visual Studio 2013 Web Developers

Team Foundation Server Allgemeines

Debugging

.NET Reference Source

Die wichtigsten Shortcuts aus dem Vortrag

CTRL+Q Suchbox
CTRL+0,C Teamexplorer Connect
CTRL+0,H Teamexplorer Home
CTRL+0,M Teamexplorer My Work
CTRL+0,P Teamexplorer Pending Changes
CTRL+ü Solütion Explorer
CTRL+ä Team Äxplorer
CTRL+M,O Collapse to definition
CTRL+M,M Collapse/Expand
ALT+CURSOR UP/DOWN Move Lines/Selection up and down
CTRL+K, CTRL+B Code Snippet Manager
CTRL+K, CTRL+X Insert Codesnippet
CTRL+M, CTRL+H Create temporary collapsable region
CTRL+M, CTRL+U Remove temporary collapsable region
CTRL+W,T ShowTasks window
CTRL+SHIFT+V Cycle through Clipboard History
ALT + F12 Peek Goto Definition
CTRL+, Navigate To
CTRL + - Navigate back (Browser back)
CTRL + SHIFT + - Navigate forward (Browser forward)
CTRL + ENTER Insert line above current line
CTRL + E, D Format Document
CTRL + E, C Comment
CTRL + E, U Uncomment
ALT+SHIFT+CURSOR Rectangular Selection
CTRL + ´ Jump to closing/opening bracket
CTRL+SHIFT+´ Select region between brackets including
CTRL+SHIFT+ö Show callstack on codemap
CTLR+ö Add item to codemap
CTRL+K, CTRL+G Page Inspector

Have fun!

Andreas Pollak
Product Marketing Manager Visual Studio (Entwicklungs- und Testwerkzeuge)
clip_image001

Leader im Magic Quadrant für ALM

Klaus Aschenbrenner: Improving Query Performance by using correct Search Arguments

(Be sure to checkout the FREE SQLpassion Performance Tuning Training Plan, where you are getting week by week via email all the essential knowledge you need to know about performance tuning on SQL Server.)

In today’s blog posting I want to talk about a very specific performance problem related to indexing in SQL Server.

The Problem

Imagine the following simple query, which you have already seen hundreds of times in your SQL Server life:

-- Results in an Index Scan
SELECT * FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = 2005 AND MONTH(OrderDate) = 7
GO

With that simple query, we request sales information for a specific month in a specific year. Not very complicated. Unfortunately that query doesn’t perform very well – even with a Non-Clustered Index on the column OrderDate. When you look at the execution plan, you can see that the Query Optimizer has chosen the Non-Clustered Index that is defined on the column OrderDate, but unfortunately SQL Server performs a complete Scan of the index, instead of performing an efficient Seek operation.

Non Clustered Index Scan

This isn’t really a limitation of SQL Server, this is the way how relational databases are working and thinking :-) . As soon as you are applying an expression (function calls, calculations) on an indexed column (a so-called Search Argument), the database engine HAS TO SCAN that index, instead of performing a seek operation.

The Solution

To get a scalable seek operation in the execution plan, you have to rewrite your query in a way to avoid the call of the function DATEPART:

-- Results in an Index Seek
SELECT * FROM Sales.SalesOrderHeader
WHERE OrderDate >= '20050701' AND OrderDate < '20050801'
GO

As you can see from the rewritten query, the query returns the same result, but we have just eliminated the function call of DATEPART. When you look at the execution plan, you can see that SQL Server performs a seek operation – in that specific case it is a so-called Partial Range Scan: SQL Server seeks to the first value, and scan until he hits the last value of the requested range. If you have to call functions in the context of indexed columns, you should always make sure that these function calls are performed on the right hand side of your column in the query. Let’s have a look at a concrete example. The following query casts the indexed column CreditCardID to the data type CHAR(4):

-- Results in an Index Scan
SELECT * FROM Sales.SalesOrderHeader
WHERE CAST(CreditCardID AS CHAR(4)) = '1347'
GO

When you have a more detailed look on the execution, you can see that SQL Server scans again the whole Non-Clustered Index. Not really scalable if your table gets larger and larger. If you are performing that conversation on the right hand side of your indexed column in the query, you can again eliminate the function call on the indexed column, and SQL Server is able to perform a seek operation:

-- Results in an Index Seek
SELECT * FROM Sales.SalesOrderHeader
WHERE CreditCardID = CAST('1347' AS INT)
GO

Another nice example where you can run into the same problems is the use of the CASE expression in SQL Server. Let’s have a look at the following query, where the column PersonType is indexed through a Non-Clustered Index:

-- Results in an Index Scan
SELECT
	CASE PersonType
		WHEN 'IN' THEN 1
		WHEN 'EM' THEN 2
		WHEN 'SP' THEN 3
		WHEN 'SC' THEN 4
		WHEN 'VC' THEN 5
		WHEN 'GC' THEN 6
	END AS ConvertedPersonType
FROM Person.Person
GO

You are calling here again a function on an indexed column, in our case the CASE expression. You can’t directly see that function call in the T-SQL query, but internally it’s nothing more than a function call. You are getting again a Scan of the Non-Clustered Index instead of a Seek operation. How can you avoid that problem? You can rewrite the query to get rid of the CASE expression. One example is a join against a Common Table Expression, which stores the needed lookup values. Let’s have a look on the rewritten query:

-- Results in an Index Seek
WITH LookupCTE AS
(
	SELECT * FROM
	(
		VALUES
			(N'IN', 1),
			(N'EM', 2),
			(N'SP', 3),
			(N'SC', 4),
			(N'VC', 5),
			(N'GC', 6)
	) tbl (PersonType, Value)
)
SELECT cte.Value FROM Person.Person p
INNER JOIN LookupCTE cte ON cte.PersonType = p.PersonType
GO

With that approach, SQL Server is able to perform a seek operation on the indexed column PersonType.

Summary

As you have seen in this blog posting, it is very important that you are NOT calling any function directly or indirectly on your indexed columns. Otherwise SQL Server has to scan your index, instead of performing an efficient seek operation. And scans will never ever scale, when your table gets more and more rows.

Please feel free to leave a comment, if you want to share other good examples where you have encountered this specific behavior.

Thanks for reading!

-Klaus

ppedv Team Blog: Data Annotations Webforms und Bootstrap ausgereizt

Auf dem Weg zum Lazy Web Developer habe ich dieses Mal den Data Annotations auf den Zahn gefühlt. In Silverlight war das richtig geiler Scheiss.

Man kann einer Klasse per Property-Attributen Regeln mitgeben. Diese werden Data Annotations genannt. Die Regeln können sich auf Darstellung, Reihenfolge oder Gültigkeit eines Propertys beziehen.

   1:  Public Class daten1
   2:      <Key()>
   3:      Property id As Integer
   4:      <Required(ErrorMessage:="brauche Daten")>
   5:      <EmailAddress(ErrorMessage:="brauche email")>
   6:      Property email As String
   7:      <Required(ErrorMessage:="musse haben")>
   8:      Property name As String
   9:  End Class

In der richtigen Umgebung werden diese Klassenattribute ausgewertet.

ASP.NET nutzt die Klassenattribute über Dynamic Data. Eingebettet in ein Datensteuerelement wertet das DynamicEntity-Steuerelement das gebundene Objekt (Itemtype) aus.

   1:      <link href="../Content/bootstrap.css" rel="stylesheet" />
   2:      <script src="../Scripts/jquery-2.0.3.js"></script>
   3:      <script src="../Scripts/bootstrap.js"></script>
   4:  </head>
   5:  <body>
   6:      <form id="form1" runat="server">
   7:      <div>
   8:          <asp:FormView ID="FormView1" DataKeyNames="id" 
ItemType="daten1"
   9:               runat="server" DefaultMode="Insert">
  10:              <InsertItemTemplate>
  11:                  <asp:DynamicEntity runat="server" ID="eins" 
Mode="Insert"/>
  12:                  <asp:Button runat="server" CommandName="Insert" 
Text="insert" class="btn btn-default"/>
  13:              </InsertItemTemplate>
  14:          </asp:FormView>
  15:      </div>
  16:      </form>
  17:  </body>

 

Die Magie geschieht im Verzeichnis Dynamic Data. Je nach Mode (hier insert), wird das Template aus EntityTemplate geladen.

image

Dieses Template wurde von mir leicht angepasst, um den Bootstrap 3 Formular-Regularien zu folgen.

   1:  <asp:EntityTemplate runat="server" ID="EntityTemplate1">
   2:      <ItemTemplate>
   3:          <div class="form-group">
   4:              <asp:Label ID="Label1" runat="server" OnInit="Label_Init"
   5:                  OnPreRender="Label_PreRender" 
CssClass="col-sm-2 control-label" />
   6:              <div class="controls">
   7:                  <asp:DynamicControl runat="server" ID="DynamicControl"
   8:                      Mode="Edit" OnInit="DynamicControl_Init" />
   9:              </div>
  10:          </div>
  11:      </ItemTemplate>
  12:  </asp:EntityTemplate>

 

Das DynamicControl-Element wird dann passend zum Datentypen durch ein Template aus dem Verzeichnis FieldTemplate ersetzt. In diesem Beispiel Integer_Edit, Text_Edit und EMailAddress_Edit.

Folgendes deklarative ASP.NET Code-Beispiel zeigt das Text-Template. Wichtig ist Display Dynamic einzustellen, um den Platz in der Darstellung nicht zu verbrauchen, wenn keine Fehlermeldung angezeigt wird. Außerdem verwendet Bootstrap für sein error HTML Template die CSS-Klasse help-block. Ergebnis ist roter Text.

   1:  <asp:TextBox ID="TextBox1" runat="server" Text='<%# FieldValueEditString %>'
   2:       CssClass="form-control"></asp:TextBox>
   3:   
   4:  <asp:RequiredFieldValidator runat="server" ID="RequiredFieldValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
   5:  <asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" Enabled="false" />
   6:  <asp:DynamicValidator runat="server" ID="DynamicValidator1" 
CssClass="help-block" ControlToValidate="TextBox1" Display="Dynamic" />
   7:   

Die ASP.NET Validation Controls haben allerdings ein Feature, das hier stört. Diese können mit einem Stern die Fehlerposition  und den beschreibenden Fehlertext in einem ValidationSummary Control anzeigen. Wir wollen aber den Fehlertext direkt unterhalb der Eingabe sehen.

Folgender übler Trick ersetzt per VB.NET Code im Page Load Event des ASCX Files den Stern und damit wird der volle Text gezeigt:

   1:  RegularExpressionValidator1.Text = ""
   2:  RequiredFieldValidator1.Text = ""
   3:  DynamicValidator1.Text = ""

Dann füge ich noch eine JavaScript-Datei hinzu, die CSS-Attribute austauscht für has-errors wenn die Eingabe nicht valid ist. Dies ist in einem anderen Blog-Artikel beschrieben.

   1:  var proxied = window.ValidatorValidate;
   2:   
   3:  window.ValidatorValidate = function () {
   4:   
   5:      var result = proxied.apply(this, arguments);
   6:      onAfter(arguments);
   7:   
   8:  };
   9:   
  10:  var onAfter = function (arguments) {
  11:      var control = document.getElementById(arguments[0].controltovalidate);
  12:      var validators = control.Validators;
  13:      var isValid = true;
  14:   
  15:      for (var i = 0; i < validators.length; i++) {
  16:          if (!validators[i].isvalid) {
  17:              isValid = false;
  18:              break;
  19:          }
  20:      }
  21:   
  22:      if (isValid) {
  23:          $(control).closest('.form-group').removeClass('has-error');
  24:      } else {
  25:          $(control).closest('.form-group').addClass('has-error');
  26:      }
  27:  };

Bei einem Submit des Formulars sieht das im Internet Explorer  so aus:

image

Sehr cool, was die ASP.NET Steuerelemente zusammen mit Bootstrap hier so zaubern. Allerdings sind sie einen Hauch zu intelligent. Es werden nämlich auch korrekt die neuen HTML5 Input-Typen gerendert (Type=”number” und Type=”email”). Moderne Browser validieren dann auch gleich mal selber was im IE bei falscher E-Mail-Adresse so aussieht:

image

Zuerst erscheint ein browserspezifisches Popup und wenn man das Feld per TAB verlässt, wird es rot eingerahmt.

Da wir uns hier in den Händen des Browsers befinden, sieht das dann Chrome auch deutlich anders. Die fehlerhafte Eingabe wird gar nicht mehr hervorgehoben und die Nummer wird von einem Updown Icon begleitet.

image

In den Bootstrap-Foren wurde das Thema auch diskutiert und dann geschlossen. Theoretisch wäre auch das Required-Attribut ein HTML5-Standard, hier erzeugt ASP.NET aber stattdessen ein DIV. Optisch besser aber nicht konsistent. Bei meiner Recherche habe ich ein Plugin gefunden, habe aber ein wenig Probleme für das Framework, das für die Unzulänglichkeiten von CSS erfunden wurde, ein Plugin zu verwenden, das die Unzulänglichkeiten des Frameworks fixed. Im ersten Test gibt es einen Konflikt mit meiner eigenen JS Library. Selbst wenn ich das fixe, kann schon morgen mit dem nächsten Nuget-Update wieder alles hin sein.

Holger Schwichtenberg: Zusammenfassung von Microsofts BUILD-Konferenz 2014

Die BUILD-Konferenz brachte Neuigkeiten zu Windows 8.x, Windows Phone, Windows Azure sowie .NET, C# und Visual Studio.

Christian Binder [MS]: Build 2014 – Ein neues Microsoft?

Die //Build2014 letzte Woche in San Francisco war für mich eine besondere Build. Der Grund dafür sind nicht etwa nur einzelne Produkt Features, die angekündigt worden sind, wie. z.B. das neue Azure Portal, welches definitiv ein Meilenstein ist und DevOps in der Cloud neu definiert, sondern viel mehr die Tatsache, dass sich ein neues Microsoft präsentiert hat.

WP_20140402_12_06_00_Pro

Like - “Developing since kindergarten … C++ is his blood … Tried them all”

Windows für 0€

Windows wird nun für Tablets und Phones bis 9 Inch Diagonale kostenfrei sein. Für mein Dell Venue Pro 8 bedeutet das, dass keine Windows Lizenzkosten anfallen. Das gilt auch für Windows im IoT (Internet of things), also kleinste Geräte, die z.B. mit dem Micro Framework laufen. Ein Beispiel hierfür ist die Netduino Platform. Für mich eine der signifikantesten Änderungen, da so ein Schritt vor Jahren nicht denkbar gewesen wäre.

Windows näher am Kunden entwickeln

Windows 8 wurde für Tablets und Touch optimiert. Die Brücke zwischen Touch und Desktop für reine Desktop Anwender hatten wir aus meiner Sicht nicht ideal gebaut. Durch die nun kürzeren Release Zyklen von Window  können wir aber näher am Kunden entwickeln und schneller Feedback einfließen lassen. Mit Windows 8.1 Update kommen nun Neuerungen, die das Arbeiten mit dem Desktop optimieren, unter anderem dann später auch das optionale Startmenü für den Desktop. Ich selbst werde es nicht mehr aktivieren, da ich die Vorteile des neuen Start Screens selbst auf einem Gerät ohne Touch schätze. Aber für alle Anwender, die noch Windows XP nutzen, wird der Umstieg dann ganz einfach.

.NET is so alive

Wer heute .NET Entwickler ist, dem stehen alle Türen offen. Ob Spiele Entwicklung mit Unity und C#, ob Cross Device Platform Apps für IPhone und Android mit C# und Xamarin, Windows Phone Apps, Windows Apps mit Hilfe der neuen Universal Windows Apps für einfaches Code-Sharing zwischen den unterschiedlichen Formfaktoren oder IoT Devices mit dem Micro Framework z.B. der Netduino Platform - You can do. Aber da ist viel mehr Innovation in .NET:

Der Core -  Ein neuer .NET JIT Compiler (Preview), der auch SIMD (Single Instruction, Multiple Data) unterstützt. Die .NET Compiler Platform (Codename Roslyn), welche die Compiler nun durch eine API öffnet und sich dadurch gerade im Bereich IDE Rectoring, Code Analyse und Diagnostik ganz neue Möglichkeiten ergeben.  Zudem ist die .NET Compiler Platform Open Source! Get the code here. Wir werden in Zukunft auch einige neue Innovationen in Visual Studio sehen, welche die .NET Compliler Platform nutzen und somit .NET noch produktiver machen. .NET Native –  C# Store Apps lassen sich mit dem C++ Backend Compiler bauen und profitieren so von einem besseren Startverhalten und Speichernutzung. .NET Native bringt die Produktivität von .NET mit der Performance des C++ Compilers zusammen.

Zudem wurde die .NET Foundation angekündigt – die Open Source Initiative für die .NET Platform und es sind schon eine ganze Reihe Projekte verfügbar. Mehr Infos unter http://www.dotnetfoundation.org

Zum Abschluss noch zwei Themen, die ich empfehlen möchte - es gibt natürlich viel mehr…..

Session Empfehlung  - Machine Learning

Die Session Developing Neural Networks Using Visual Studio greift wie der Titel schon sagt Neurale Netzwerke auf, was durchaus den einen oder anderen Leser an mentale Qual und Folter erinnert. Es ist aber die Grundlage für Machine Learning und die Session gibt nicht nur einen kompakten Einstieg, sondern zeigt auch interessante Anwendungsfälle. Denkt man z.B. an gewachsene Menüstrukturen, kommt man schon auf die Idee, warum nicht ein Neurales Netzwerk Anwendung finden könnte, um aus meinem Nutzungsverhalten die Menüs intelligent und dynamisch  aufzubauen. Spannend.

Session Empfehlung  - Deep Dive into Git with Team Foundation Server

Martin und Ed hatten eine echt gute Session zum Thema Deep Dive into Git with Team Foundation Server. Vor allem die Unterscheidung, für welchen Anwendungsfall sich Git oder TFVC empfiehlt, halte ich für besonders wichtig, da ich diese Fragen häufig selbst gestellt bekomme.

image

Viel Spass mit den //Build 2014 Recordings

codefest.at [MS]: Windows Phone 8.1–Ein Feuerwerk an Neuerungen

Letzte Woche wurde auf der Build Windows Phone 8.1 vorgestellt und dadurch auch jede Menge Neuerungen die mit dem neuen Windows Phone verbunden sind.

Wir haben daher kurzfristig unseren Vortrag am Microsoft Day zu Windows Phone im Unternehmen umgeändert, und stellen in der Session stattdessen Windows Phone 8.1 vor. Ihr könnt in der Session einige der neuen Lumia Geräte sehen. Außerdem zeigen wir euch, wie Windows Phone 8.1 aussieht und welche Verbesserungen es in der User Experience für Endanwender gibt.

Natürlich werfen wir auch ein Licht auf die vielen Features, die als Unterstützung für Unternehmen eingebaut wurden, damit Windows Phone optimal als Firmengerät eingesetzt werden kann. Wir schauen uns hier Beispiele vom gesamten Mobile Device Management an.

Nicht zu vergessen sind die unzähligen Neuerungen im Bereich von Windows Phone Entwicklung. Wir zeigen euch, welche Möglichkeiten dem Developer nun zur Verfügung stehen, wie man Windows Phone Apps schreiben kann und was es mit One Windows auf sich hat.

Die Session ist bepackt mit so vielen neuen Dingen, dass man nur von einem Feuerwerk sprechen kann. Lass Dir die Österreich-Vorstellung von Windows Phone 8.1 nicht entgehen!

Titel: Windows Phone – Ein Feuerwerk an Neuerungen
Wann: 8. April 2014, 11.30 Uhr
Wo: Forum – Hofburg. Wien

Ralf Westphal: Arbeitszeiteinteilung für Veränderung

Der Wunsch, irgendwie besser Software zu entwickeln, ist weit verbreitet. Irgendwas stört in jedem Projekt. Irgendwie hakt es in jedem Team. Viele leiden unter der Last von Legacy Code. Andere kämpfen mit Qualitätsproblemen oder unzuverlässiger Lieferung. Zur Verbesserung der Situation lässt sich dann natürlich allerlei raten. Mehr Clean Code, konsequentere Agilität, bessere Infrastruktur,

Norbert Eder: Technic Lego neu definiert

Mit Lego und einem Raspberry PI können sehr coole Projekte umgesetzt werden. Hier ein kleines Video von den Grazer Linuxtagen, welches ein ebensolches Projekt zeigt.

ppedv Team Blog: Form-Validierung für Bootstrap

Es gibt verdammt viele Möglichkeiten, um Benutzereingaben zu validieren. Im Webumfeld werden es sogar mehr statt weniger. Hinzu kommen Anforderungen an das Design. Client oder Server? Ganz schön viel für einen kleinen Blogartikel, der sich um ASP.NET-Formulare in Verbindung mit Bootstrap 3 kümmert.

Bootstrap ist ein Framework für einfacheres Webdesign. Responsive Design fast ohne CSS anzufassen. Microsoft setzt in Visual Studio 2013 und seinem One ASP.NET Template auf die aktuelle Version Bootstrap 3. Ist also schon drin. Ideal also für eine schnelle Validierung am Client.

Das HTML Template setzt sich aus geschachtelten DIV zusammen und vor allem dem Attribut has-error. In der  Version 2 lautete das noch control-group und error.

   1:   <div class="form-group has-error">
   2:          <label class="control-label" for="text1">Feldbeschreibung
</label>
   3:          <div class="controls">
   4:              <input type="text" class="form-control" id="text1">
   5:              <span class="help-block">Fehlermeldung</span>
   6:          </div>
   7:  </div>

und sieht dann so aus. Der Fehler ist sozusagen hart verdrahtet.

image

Nun stellt sich sowohl für den ASP.NET MVC und auch den Webforms Frontend Designer die Frage, wie man die Validation Controls bzw. HTML Validation Helper dazu bewegt da mitzuspielen. Das Problem liegt vor allem darin, dass die Fehlermeldung einen übergeordneten Node im HTML Dom verändern muss. Aus Programmierersicht ist es ohnehin verpönt, Elemente (oder Objekte) in Abhängigkeit zu stellen.

Die Alternative, komplett neue Steuerelemente zu entwickeln, erscheint wenig verlockend.

Betrachten wir die Eingabevalidierung mit ASP.NET Web Forms unter Anwendung der vorigen Bootstrap HTML Vorlage. Es soll geprüft werden, ob die Eingabe eine gültige E-Mail-Adresse ist. Visual Studio schlägt in den Control-Eigenschaften die passende Regular Expression vor.

   1:  <div class="form-group" id="test1">
   2:          <asp:Label ID="Label2" runat="server" Text="Beschriftung"
   3:           CssClass="col-sm-2 control-label" />
   4:          <div class="controls">
   5:              <asp:TextBox ID="TextBox1" runat="server" 
CssClass="form-control">
   6:  </asp:TextBox>
   7:              <asp:RegularExpressionValidator 
ID="RegularExpressionValidator1" runat="server"
   8:                  SetFocusOnError="true"
   9:                  ErrorMessage="RegularExpressionValidator" 
ControlToValidate="TextBox1"
  10:  ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">
  11:  </asp:RegularExpressionValidator>
  12:          </div>
  13: </div>    

Als nächstes kommt JavaScript und JQuery Magic zum Einsatz. Mein großes Problem war herauszufinden, wo man während der Validierung einhaken kann. Das Validator Control blendet dynamisch ohne Postback die Fehlermeldung ein bzw. aus - dank moderner unobtrusive Validation von ASP.NET Webforms auch mit JQuery Validierung. Im HTML Code wird ein SPAN Element erzeugt. Data-Attribute werden für die Validierung verwendet.

   1:   <input name="ctl00$Inhalt$TextBox1" type="text" 
id="Inhalt_TextBox1"
   2:  class="form-control" />
   3:   
   4:  <span data-val-controltovalidate="Inhalt_TextBox1" 
data-val-focusOnError="t"
   5:  data-val-errormessage="RegularExpressionValidator" 
   6:  id="Inhalt_RegularExpressionValidator1" data-val="true" 
   7:  data-val-evaluationfunction="RegularExpressionValidator
EvaluateIsValid"
   8:  data-val-validationexpression="\w+([-+.&#39;]\w+)*@\w+
([-.]\w+)*\.\w+([-.]\w+)*"
style="visibility:hidden;">
RegularExpressionValidator</span>
   9:          </div>

Bleibt die Frage, wie man aus dem SPAN da, oder nicht da, auf ein übergeordnetes DIV kommt. Ginge, aber ich habe ein Event gefunden, das schon seit Ewigkeiten in der Library existiert, ValidatorValidate.

Diese Methode wird dann überschrieben, wie man das aus OOP so kennt, um seine eigene Logik (onAfter) hinten dran einzufügen. Dann wird die CSS Klasse has-error zugewiesen, wenn ein Fehler auftritt.

   1:  <script>
   2:   var proxied = window.ValidatorValidate;
   3:         window.ValidatorValidate = function () {
   4:          var result = proxied.apply(this, arguments);
   5:          onAfter(arguments);
   6:         };
   8:         var control = document.getElementById(arguments[0].
controltovalidate);
   9:         var validators = control.Validators;
   7:         var onAfter = function (arguments) {
  10:         var isValid = true;
  11:         for (var i = 0; i < validators.length; i++) {
  12:                  if (!validators[i].isvalid) {
  13:                      isValid = false;
  14:                      break;
  15:                  }
  16:              }
  17:             if (isValid) {
  18:                  $(control).closest('.form-group').
removeClass('has-error');
  19:              } else {
  20:                  $(control).closest('.form-group').
addClass('has-error');
  21:              }
  22:          };
  23:  </script>

 

Um ehrlich zu sein, bin ich mir nicht sicher, was ich mir im Detail damit einhandle. Falls es unter den Lesern welche gibt die dazu Feedback haben, per mail an hannesp at ppedv.de oder Facebook.com/preishuber.

Jedenfalls ist der Aufwand nun überschaubar. Einfach als JS-Datei ausgelagert und am besten in der Masterpage included.

Code-Inside Blog: Gegen das Gesetz verstoßen: X Jahre Haft. Gegen die Terms of Use verstoßen: Bann auf Lebenszeit. Danke Google & co.

Bei fast allen Diensten die man im Internet nutzen kann muss man den “Terms of use” zustimmen. Völlig logisch dass da natürlich drin steht was erlaubt und was nicht. Wenn man gegen diese Regelungen verstößt hat das Unternehmen natürlich das Recht etwas dagegen zu unternehmen. In der heutigen Welt beherrschen einige wenige Unternehmen die digitale Identität. Das ist einerseits enorm praktisch, auf der anderen Seite enorm beängstigend – in vielen Bereichen. Verstößt man nun gegen diese Regelungen kann es sein das Google & co. sich dazu entschliesst den Account zu sperren bzw. zu beschneiden. Das Ganze gilt natürlich auf Lebenszeit. Wenn mit diesem Account jetzt aber auch geschäftliche Sachen abgewickelt werden kann diese Sperre plötzlich auch im “echten” Leben fatale Folgen haben.

Banned for lifetime – Android & Google Wallet

Ich bin letzte Woche auf einen Artikel von einem Android Entwickler gestoßen. Um die Geschichte kurz zu machen: Er hatte diverse “YouTube Channels” in Apps verwandelt, damit seine Kinder diese einfacher finden können – das ganze soweit er sagt auch kostenlos. Nachdem er 10 dieser Apps gemacht hatte und Google 3 von diesen Apps aus dem Store nahm wurde sein Android Developer Account gesperrt und zugleich auch sein Google Wallet Konto. Einspruch nützte natürlich auch nichts.

Google Adsense – “Account disabled”

Die Geschichte hat mich daran erinnert das Google mich auch auf Lebenszeit vom Google Adsense Program ausgeschlossen hat. Kein Witz, Grund: “Invalid Click Activity”. Ich will nicht bestreiten dass ich mal auf die Werbung geklickt hatte die ich auf meinen Blog angezeigt war, allerdings würde ich den “Schaden” jetzt im Cent bis Euro Bereich sehen. Naja, gegen die Richtlinie verstoßen und ausgeschlossen, Shit Happens. Das Ganze ist nun schon mindestens 4 Jahre her und so dachte ich, dass Google mir inzwischen verzeiht:

Hello,
Thanks for the additional information provided in your appeal, we 
appreciate your continued interest in the AdSense program. After thoroughly 
reviewing your account data and taking your feedback into consideration, 
our specialists have confirmed that we’re unable to reinstate your AdSense 
account.

Nope. Einspruch natürlich sinnlos. Beide Beispiele beziehen sich jetzt auf Google Dienste, aber vermutlich gibt es auch ähnliche Fälle bei Microsoft, Apple usw.

Mir persönlich ist das Google Adsense Programm aktuell ohnehin egal, aber ich kann mir vorstellen dass solche Aktionen nicht gerade zur Vertrauensbildung beitragen.

ppedv Team Blog: Build-Ankündigungen für Microsoft Azure

Auf der Build-Konferenz, die in dieser Woche in San Francisco stattfand, gab es einige neue Meldungen, natürlich auch zum Thema Microsoft Azure, wie sich die Cloud-Lösung seit dieser Woche nennt.

  • Neues Portal

Seit Donnerstag Abend steht unter https://portal.azure.com/ das neue Portal für Microsoft Azure als Preview zur Verfügung. Dieses neue Portal verknüpft dabei Microsoft Azure und Visual Studio Online. Es soll im Laufe der Zeit um weitere Tools von Microsoft und deren Partnern erweitert werden und auch auf die Wünsche der Kunden angepasst werden.

  • Neue Basiskategorie für Web Sites

Die neue Einsteigerkategorie für Web Sites (Basic) bietet Unterstützung für small, medium und large Virtual Machines. Gegenüber der Standardedition liegen die Preise um 33 % niedriger. Die folgende Grafik zeigt einen Vergleich der verschiedenen Angebote:

Wie Sie aus der Grafik auch erkennen können, wurden die Standardinstanzen auch verbessert. So können Kunden ohne weitere Kosten fünf SNI (Server Name Indication) und ein IP SSL Zertifikat hochladen und nutzen. Automatische Skalierung auf bis zu 10 virtuellen Instanzen und tägliche Backups runden das Angebot ab.

  • Basic Tier auch für Compute Instanzen

Auch im Bereich Cloud-Dienste wird neben der Standardversion eine Basicversion angekündigt, die um 26,67% günstiger sein wird, jedoch kein Loadbalancing und automatische Skalierung unterstützt. Diese Instanzen sind vor allem als Testserver und während der Entwicklung geeignet.

  • Azure Active Directory Premium

Azure Active Directory Premium ist ab sofort generell verfügbar. Alle Kunden, die diesen Service in der Preview genutzt haben, können sich bis zum 1. Juli 2014 entscheiden, ob sie den Dienst bezahlen wollen oder danach das normale Azure Active Directory kostenlos nutzen wollen. Die Premiumversion unterstützt Synchronisation mit dem lokalen Active Directory, Single Sign On und Multifactor Authentifizierung.

  • Scheduler-Dienst verfügbar

Auch ein Scheduler-Dienst ist ab sofort verfügbar. Mit dem Scheduler können Sie Jobs in der Cloud erstellen, die zuverlässig Dienste inner- und ausserhalb der Cloud aufrufen können.

  • Autoskalierung

Applikationen können jetzt so konfiguriert werden, dass sie automatisch auf Basis der aktuellen Nutzung hoch oder auch runterskalieren. Autoskalierung ist möglich für Virtuelle Maschinen, Cloud-Dienste, Web Sites und Mobile Services.

  • weitere verfügbare Dienste

Des Weiteren wurden folgende Dienste generell verfügbar gestellt:

- Visual Studio Online

- Virtual Network Dynamic Routing Gateway und Point-to-Site VPN

- Azure Automation

- Azure Backup 

ppedv Team Blog: Evolution statt Revolution

Nachdem der Staub sich rund um die alljährlichen Ankündigungsreigen der Redmonder Software-Schmiede zu legen beginnt, ist es Zeit ein erstes Fazit zu ziehen. Was bringt uns die Zukunft bzw. was stellt sich Microsoft darunter vor?

Wenn man es ganz nüchtern betrachtet, bleibt eigentlich nur ein Windows Update für 8.1, ein Phone Update von 8 auf 8.1 und eine Reihe von Detail-Änderungen übrig. Daneben noch die faktisch folgenlose Veröffentlichung des Quellcodes einiger neuer Bibliotheken, heute Open Source genannt.

Wer eine Dekade zurückblickt, wird sich erinnern, dass die TechEd Developer sich mit aktuellen und ganz nahen Technologien beschäftigte und die PDC, die Vorgängerin der BUILD, mit den über die nächsten ca. 18 Monaten kommenden. Die BUILD 2014 präsentierte am 2.April ein kleines Windows Update, das am 8.April öffentlich verfügbar sein wird. So ist die Welt heute. Gerade mal eine Woche Zukunft. Roadmaps konnte man in den Slides keine entdecken.

Vor rund fünf Jahren war Windows Mobile 6.5 angesagt. Mit einem kolportierten Marktanteil von ca. 19%. Allerdings war Apple unaufhaltsam auf dem Vormarsch und so entschlossen sich die Redmonder zu einem radikalen Schnitt: es den Jungs aus Cupertino gleich zu tun.

Ich erinnere mich noch gut an ein frühes Meeting bei Microsoft. Ein Kreis erlauchter externer Experten, eine Handvoll Microsofties und meine Wenigkeit. Das Produkt, das da vorgestellt wurde, hatte alle Nachteile von Apple gewonnen und die Vorteile von Microsoft verloren. Ich werde heute noch auf meine unbarmherzige Kritik angesprochen. Und ich habe mit jedem Strich und Punkt Recht behalten. Meine damaligen Vorschläge werden jetzt umgesetzt. Der Marktanteil dümpelt heute noch unterhalb des damaligen Windows Mobile rum. Dennoch hatte auch Microsoft Recht. Es musste ein harter Kurswechsel her. Windows Mobile hatte kein Marktpotential für die Zukunft.

Rund zweieinhalb Jahre später, auf der ersten BUILD, wurde dann Windows 8 angekündigt. Ich war persönlich in Anaheim dabei und habe mich von der Begeisterung anstecken lassen. In einem persönlichen Dialog mit einem Produktmanager wurde die Problematik des Rollouts angesprochen. Er war überzeugt, dass der Appstore-Zwang von den Kunden angenommen wird. Ich nicht. Ein anderer wichtiger Produktmanager war überzeugt, dass bald ohnehin nur mehr touchfähige Devices ausgeliefert werden. Ein folgenschwerer Irrtum, wie sich aus heutiger Sicht zeigt. Der wesentlichste Fehler ist uns und damit meine ich Microsoft und mich, in der  Einschätzung der Verbreitung von Windows 8 und Devices unterlaufen. Meine persönliche Prognose war: 100 Millionen Touch Devices bis 31.Dezember des Erscheinungsjahrs, sonst wird Balmer seinen Hut nehmen müssen. Es waren bei weitem nicht so viele und Balmer ist Geschichte.

Ganz wesentlich ist aber die falsche Consumer-Strategie. Consumerization von IT ist zwar Tatsache, wie auch bei HTML5, aber deren Folgen sind völlig falsch eingeschätzt worden. Die Unternehmen haben keine APPS erstellt. Punkt.

Windows 8 hatte nie ein Qualitätsproblem. Es war schön, modern, einfach zu bedienen. Auf Tablets für den Neueinsteiger völlig intuitiv. Eine Sensation ohne Startbutton. Es sind die über 1 Milliarde Microsoft-Benutzer, die nicht mitspielen. Folgerichtig kann man in den Blogs und Tweets im Tenor lesen, was es eh jeder schon die ganze Zeit sagt: Hört den Kunden zu. Steve Jobs und Steven Sinofsky waren anderer Meinung: Innovation kommt nicht aus Marktforschung.

Ganz anders die Keynotes der BUILD 2014. Wir haben zugehört, hier habt Ihr das Resultat. Auch ein Startmenü gibt es dazu. Und wir nehmen euch euer geliebtes .NET und XAML nicht weg. JavaScript erwähnen wir gar nicht, weil ihr es hasst.

Die Teilnehmer sind begeistert. Twitter quillt über von positiven Feeds: Beste BUILD ever. Vor allem die gemeinsame Codebasis für Phone und Windows wird gelobt. Auch die vereinfachte Sideloading Policy, die faktisch den Store aushebelt, stößt auf Begeisterung.

Die Realität bildet das aber nur zum Teil ab. Weite Teile des Developer Eco Systems beschäftigen sich heute mit HTML5 als Frontend-Technologie. Ich halte diese zwar für grottig, aber vorhanden. Da das Problem mit dem Standard und Browsern systemimmanent ist, erwarte ich keine relevante Besserung. In Angesicht dessen bin ich immer wieder erstaunt, welche großartigen Ergebnisse trotz widriger Umstände erzielt werden.

Diese Community wird auch mit dem Honig Open Source und Nuget kaum kleben bleiben. Das sind die Leute, die nicht auf die BUILD gehen.

Aus dem Applaus und den Besucherzahlen der aufgezeichneten Sessions lassen sich ein paar Trends erkennen. C# und .NET sind weiter top angesagt. Multiplattform-Entwicklung auf dem .NET-Technologiestack wird eindeutig gewünscht und von XAMARIN bedient. Azure ist trotz Scott Guthrie bei weitem nicht das führende Thema.

Schon im Vorfeld hat Microsoft eine Art Office für die Apple-Plattform gelauncht. Ein Eingeständnis der schwindenden Bedeutung von Windows. Dies wird auch mit einem Startmenü nicht besser werden. Die Fokussierung auf das angestammte Publikum, die Vereinheitlichung der Plattform Xbox, Windows und mobile werden helfen, nicht noch weitere Kunden zu vergraulen.

Die nächste Welle wird allerdings woanders an den IT-Strand laufen: das Internet of Things, oft ohne UI, aber damit mit hohem Bedarf an Service-Kommunikation. Davon sah man im BUILD-Programm recht wenig.

Hannes Preishuber besucht seit rund 15 Jahren Microsoft-Konferenzen. Er war Teilnehmer der legendären Hailstorm PDC, deren Visionen und Produkte nie Realität wurden. Auch Projekt Oslo und die Programmiersprache M kennt heute keiner mehr. Obwohl Clippy das selbe Schicksal erleiden musste, war er kein PDC Announcement. 2003 diskutierte er auf der PDC in Los Angeles mit dem noch unbekannten Miguel de Icaza über .net und dessen von Microsoft ungewünschte Implementierung als Mono. Die BUILD Konferenz 2014 besuchte er nur virtuell. Trotz entsprechender Gerüchte nicht wegen des Essens.

friends header

bloggers headline

links header

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