.
Anmeldung | Registrieren | Hilfe

.NET-Blogs Archiv Oktober 2012

Verfügbar : Visual Studio 2012 Update 1

30.10.2012 13:55:00 | Christian Binder

Das erste Visual Studio Update ist jetzt verfügar. Download

++ An Alle C++ Entwickler ++

XP Support für den neuen Compiler kommt mit diesem Update mit!!!!!!
Wer auf der ADC C++ 2012 war, dem ist bekannt, dass wir dort das Thema intensiv diskutiert hatten und Euer Feedback das ermöglicht hat.

Hier eine Liste der Neuerungen: Mehr Details hier

  • Extend TFS server side path limits from 260 characters to 400 characters
  • Usability improvements for Version Control
    • Associate multiple bugs with a checking at once in the Add by ID field (i.e. comma separated)
    • Toolbar button to show/hide deleted items in the source control explorer
    • Copy the name of a changeset/shelveset from the Changeset/Shelveset Details page
    • Find a Shelveset by name from the Find Shelvesets page
    • Include/exclude all items except those that are selected
    • Know if my detected changes are adds or deletes before clicking the link
    • Navigate to an item in source control explorer from pending changes page
    • Undo changes to a file from the editor context menu
  • Kanban support in TFS Web Access
  • TFS web access usability improvements
    • Drag and drop queries and query folders
    • Drag/drop between User Stories and People in the Taskboard
    • Drag a task to a person to assign it in the Taskboard
    • Expand and Collapse the left navigation pane
    • Remember the state of the splitters
    • Animate Taskboard tiles on drop
    • Next/Previous arrows on WIT form
    • Updated navigation styling
    • Links and Attachments in WIT form shows counts
  • Sharepoint testing improvements
    • Load testing support for SharePoint
    • Unit test emulator for SharePoint
    • Coded UI test support for SharePoint
    • Intellitrace collection plan for SharePoint
  • Manual testing improvements
    • Editing of test cases from inside the test runner
    • Code coverage support for manual testing of web apps
    • Hierarchical query support
    • Pause manual testing session and later resume a test case
    • Deep copy of a test plan to better support release management
    • Publish test results to TFS from command-line
  • Coded UI testing improvements
    • Cross browser testing for coded UI testing (IE, Chrome, Firefox, …)
    • Usability improvements for Coded UI tests
  • SCVMM 2012 SP1 support with Lab Management for Windows 2012 hosts
  • VSUpdate support for Microsoft Test Manager for automatic update notification
  • Unit testing improvements
    • Windows Store C++ unit testing enhancements
    • Windows Store Unit Test library enhancements
    • Traits support for all adapters
    • Unit Test Grouping and Filtering in Test Explorer Window
  • Easier installation of unit test adapters on TFS build machines using Nuget
  • Code Map – Incremental discovery and visualization of your application architecture and dependencies
  • IntelliTrace Integration with System Center
  • Integrate Blend Windows Phone Tooling
  • Multiscale image support for manifest content
  • JavaScript Memory Profiling
  • Mixed Managed/Native Debugging Support for Store Apps
  • ARM Native Dump Debugging Support
  • Enable XP targeting with C++

Das Event : Visual Studio ALM Days 2012

30.10.2012 11:42:22 | Christian Binder

Es ist wieder so weit. Die Visual Studio ALM Days 2012 gehen am 28. und 29. November in die nächste Runde. Die Konferenz ist der Treffpunkt der Microsoft ALM Community.

image

Natürlich stehen wieder die aktuellen und Trends und Neuerungen im Fokus, aber auch interessante Beiträge und Erfahrungsberichte aus den verschieden Industriezweigen so z.B. zum ersten Mal mit dabei die SAP. Aus der Produkt Gruppe haben wir wieder einige Sprecher vor Ort, ideal sich Auszutauschen und Feedback zu geben. Brian Harry General Manager Team Foundation Server, Sam Guckenheimer Visual Studio Product Owner, Dirk Bäumer Principal Software Development Engineer , Jean-Marc Prieur Senior Program Manager Visual Studio und viele anderen Experten aus der Community.

Warum Windows 8 und Windows Phone 8 ein Top Team für Unternehmen ist, werde ich mit Daniel Meixner und Frank Prengel am Management Day zeigen. Natürlich direkt nach dem Mittagessen…..

Mehr Informationen und ein kurzes Video zur Agenda findet Ihr hier.

“Konferieren ist das Ziel einer Konferenz – man kann immer lesen, oder das Internet nutzen, aber mit Leuten reden, zusammenzukommen, Ideen auszutauschen, - diese Gelegenheit hat man selten”  Sam Guckenheimer

Was mir an Windows 8 gefällt –”Suche unter Windows 8” – Teil 10 von 10

30.10.2012 07:09:44 | Gregor Biswanger

Es gibt unterschiedliche Meinungen über das neue Betriebssystem. Hier möchte ich mit einer kleinen Video-Serie, meine Top 10 Lieblingsfeatures aufzeigen. Weitere interessante Informationen findet ihr auch unter windows8-live.de. Viel Spaß!

 

Was mir an Windows 8 gefällt

Visual Studio Evolution 2012 Videos verfügbar

25.10.2012 12:34:42 | Christian Binder

Events | MSDN Online

Am 1. Oktober fand in Düsseldorf die Visual Studio Evolution 2012 statt. Visual Studio 2012 und .NET 4.5 waren der Fokus der Evolution und über 600 Teilnehmer waren vor Ort. Wohl wissend, dass nicht Jeder Zeit hat nach Düsseldorf zu reisen, haben wir von den Sessions Videos aufgenommen. Zwar können Videos die gute Stimmung nicht in gleicher Weise transportieren, dennoch kann man so noch mal die ein oder andere Session sich anschauen.

Hier geht’s zur Agenda, hinter der die  Videos der VS Evolution 2012 verknüpft sind.

Die Windows 8 App .NET Feature Catalog, die in der Keynote gezeigt wurde, gibt’s hier zum Download.

Ein Punkt, der mir in vielen Gesprächen aufgefallen ist, ist die Technologie Diskussion HTML5/JS vs. XAML .NET oder natives C++. Grundsätzlich wird aus meiner Sicht dieses Thema meist viel zu emotional diskutiert, aber das muss vielleicht auch so sein. Fakt ist, dass Windows 8 für die App Entwicklung bekanntlich mehrere Optionen anbietet, HTML5/JS, XAML/C#/VB, XAML/C++, DirectX, was Entwicklern und Teams mit unterschiedlichem technologischen Hintergrund, die Entwicklung für die Plattform vereinfachen soll und auch hybride Szenarien ermöglicht. Dariusz Parys hat hier mal seine Gedanken zur App Entwicklung und den möglichen Technologien aufgezeigt. Der Industrietrend Apps zeigt, dass die Ziel Plattformen für die Technologie Entscheidung ein sehr großen Einfluss hat. Aus meiner Sicht aber auch die Komplexität der Anwendung, die realsiert werden muss. Hier bieten die verschiedenen Technolgien nicht die gleichen Möglichkeiten.

Obwohl wir mit der VS Evolution 2012 hauptsächlich den Fokus auf .NET Entwicklung gelegt haben und Ankündigungen wie Rosyln hier sehr viele neue Möglichkeiten erschliessen werden, gibt es natürlich auch Neuerungen im Bereich von HTMl/CSS/JS für Webentwickler, wie deutlich verbesserter Support für CSS oder die Ankündigung von TypeSkript. Aber auch im Bereich von C++ gibt es neues mit VS 2012 und wird es weiter Neuerungen geben wie z.B. verbesserter Support für Rest Services für die Cloud siehe Casablanca. Die Evolution geht weiter und wir sind dabei.

Developer Openspace 2012 – Erneut ein Erlebnis

23.10.2012 21:19:14 | Hendrik Loesch

Nun ist er vorbei, der Developer Openspace 2012 und hat mal wieder einen bleibenden Eindruck in meinem Langzeitgedächtnis hinterlassen. Dies fing schon mit dem interessanten und lehrreichen Workshop zu Windows Azure an. Danke an der Stelle an Sascha Dittmann für die (kostenlos) dargebotenen Informationen und die spätere Session zu Azure Service Bus. Damit sind wir […]

Aussehen von VS2012 an VS2010 anpassen

23.10.2012 17:53:00 | Peter Bucher

Allen denen es gleich geht wie mir und nicht so viel mit der neuen Oberfläche von Visual Studio 2012 anfangen können finden zumindest eine teilweise Lösung.

Zuerst das Endergebnis: VS2012 in neuem Look

1. Für ein anderes Farbschema gibt es den Visual Studio 2012 Color Theme Editor.
Blau entspricht dabei in etwa den Farben von Visual Studio 2010.

2. Und für die Icons, die nach meinem Geschmack sehr trist daherkommen...

  => 

...gibt es den Visual Studio Icon Patcher.

Thomas Schissler hat mein Blogpost aufgegriffen und hat noch ein Tipp bekommen, um Menuicons zu tauschen.

3. Dies lässt sich mit NiceVS bewerkstelligen.

Hier nochmals die Links zu allen Tools:

Entwickler erobern Leipzig

21.10.2012 19:11:00 | Martin Hey

Jedes Jahr im Oktober gibt es in Leipzig eine Invasion von Entwicklern. Was als Event für .NET Entwickler begann wurde dieses Jahr konzeptionell etwas erweitert und hat nun den Namen Developer OpenSpace. So richtig hat sich mir die Notwendigkeit dieser Änderung noch nicht erschlossen, schließlich war es auch bisher schon so, dass sich immer auch Sessions zu eher .NET-fremden Themen oder sagen wir mal besser Randthemen aus dem Blickwinkel eines .NET Entwicklers gefunden haben. Das ist auch ganz gut - ergibt sich so doch der ein oder andere Blick über den Tellerrand. Und es schadet auf keinen Fall, mal was von Java oder Ruby gesehen zu haben. Ich persönlich sehe dieses Wochenende immer wieder als gute Gelegenheit für einen Austausch über Erfahrungen oder um neue Ideen oder Denkanstöße zu bekommen.

Continous Deployment

Was die Überschrift Continous Deployment hatte und wohl anfänglich eher die Intention hatte, thematisch in Richtung Rollout zu gehen und vielleicht auch darin, die Admins mit ins Boot zu holen, führte initial dazu, dass wir uns ziemlich lange daran aufhielten zu klären, welche Tools für Projektverwaltung, Issuetracking, Testing und Continous Integration in Verwendung sind und was die einzelnen Schmerzen in der Verwendung oder auch deren Vorteile sind. Ich denke, in den letzen 10 Minuten sind wir dann auch endlich zum eigentlichen Thema gekommen.

Ich für meinen Teil konnte mitnehmen, dass meine bisher gewählte Tooling-Landschaft ganz gut ist und dass es offenbar noch keine wirkliche Patentlösung über den Schritt des "Der CI-Server erstellt ein unitgetestetes Deploymentpakt." hinaus gibt. Ich bin mir auch nicht ganz sicher bis zu welchem Schritt diese gehen könnte, schließlich sind die Anforderungen für eine solche Lösung ziemlich speziell. Schon allein das Deployment im Testszenario ist bei Desktop-Anwendungen, die man auf möglichst vielen Denktop-Betriebssystemversionen testen möchte mit diversen Patchleveln eine ganz andere als bei Webanwendungen, bei denen in der Regel der Server klar ist und hier eher die technologische Hüde steht, den finalen Deploymentstep auf die Produktion mit ggf. notwendigen VPN-Verbindungen technologisch automatisiert zu meistern.

TypeScript, CoffeeScript, Dart

Bisher hatte ich nur einen Blogpost zum Thema TypeScript überflogen und CoffeeScript aufgrund des notwendigen Einarbeitungsaufwandes für das Team auch verworfen. Aus diesem Grund war es thematisch spannend, etwas tiefer in TypeScript eintauchen zu können und zu erfahren, welche anderen Erfahrungen es gibt. Hätte es TypeScript schon vor 3 Jahren gegeben, ich glaube der Einarbeitungsaufwand für mich als Entwickler, der eher aus einer streng typisierten Welt kommt, wäre wesentlich einfacher gewesen - zum einen weil man durch die zugegeben rudimentäre Typisierung mit 3 Datentypen einfacher auf Fallstricke hingewiesen wird, zum anderen weil solche Konstrukte wie Klassen und Konstruktoren auf der TypeScript-Seite so übersichtlich gegenübergestellt sind, dass man schnell versteht, wie die JavaScript-Repäsentation aussieht.

Twitter Bootstrap und UI Frameworks für's Web

Die Funktionalität von Bootstrap verwenden, ohne die Individualität der Webseite zu verlieren? Erprobte UI-Prinzipien verwenden, und trotzdem nicht aussehn wie Twitter? Solche und ähnliche Fragen waren Kern der Session. Es ging darum, ob und wann es sich lohnt, Bootstrap als Basis zu nehmen und hier Anpassungen vorzunehmen oder ob es eher praktikabel ist, ein Gridlayout oder eine leere HTML-Seite zu Basis zu nehmen und darauf aufbauend Funktionalitäten hinzuzufügen. Die Quintessenz: Es kommt darauf an. Ich für meinen Teil bleibe wohl vorerst bei dem bisherigen Verfahren: Wenn der Kunde das Twitter-Layout gut findet und daran nur wenige Anpassungen möchte oder der Fokus mehr auf Funktionalität als auf Individualität liegt, sind Gridsysteme oder Bootstrap eine gute Wahl. Ist eine individuelle Lösung gefragt, dann wird auch individuell entwickelt.

Zum Ende kam noch die Frage hoch nach Sketch- oder UI-Mocking-Tools. Die Antworten überraschten nicht viel: PowerPoint, Sketchflow, Balsamiq, kuler und weitere Altbekannte.

Der Rest von REST

JSON kennt wohl jeder Webentwickler. Und seit ASP.NET MVC 4 und der WebAPI spielt es auch in der .NET-Welt eine entscheidende Rolle. Aber REST geht noch weiter als das was wir alle kennen und was out-of-the-box mit den Tools mitkommt. Welche Punkte überliest man eigentlich gern in der REST-Spezifikation und was hat es mit Hypermedia-Elementen auf sich und wie kann man diese sinnvoll in diesem Kontext verwenden? Welche Möglichkeiten bieten sich durch die Verwendung und welche Vorteile ergeben sich dadurch?

Für mich haben sich hier ein paar Denkanstöße ergeben, die sich aber hauptsächlich darauf beziehen, wie man vorgehen könnte, wenn man mal eine öffentliche API bereitstellen möchte, und weniger eine interne Schnittstelle, die nur für einen einzelnen Client vorgesehen ist.

Big Data

Worum ging es? Hadoop! Wer normalerweise mit relationalen Datenbanken oder NoSQL in überschaubarem Ausmaß zu tun hat, auch für den ist es spannend mal herauszufinden, wie man mit wirklich vielen Daten umgeht. Schon alleine aus diesem Aspekt war ein kleiner Einsteig und zwei, drei Beispiele in Hadoop ganz interessant.

 

Nach den Sessions ist vor dem Bierchen. Und so endete auch dieser Tag mit lockeren Gesprächen in geselliger Runde.

Entwickler erobern Leipzig

21.10.2012 19:11:00 | Martin Hey

Jedes Jahr im Oktober gibt es in Leipzig eine Invasion von Entwicklern. Was als Event für .NET Entwickler begann wurde dieses Jahr konzeptionell etwas erweitert und hat nun den Namen Developer OpenSpace. So richtig hat sich mir die Notwendigkeit dieser Änderung noch nicht erschlossen, schließlich war es auch bisher schon so, dass sich immer auch Sessions zu eher .NET-fremden Themen oder sagen wir mal besser Randthemen aus dem Blickwinkel eines .NET Entwicklers gefunden haben. Das ist auch ganz gut - ergibt sich so doch der ein oder andere Blick über den Tellerrand. Und es schadet auf keinen Fall, mal was von Java oder Ruby gesehen zu haben. Ich persönlich sehe dieses Wochenende immer wieder als gute Gelegenheit für einen Austausch über Erfahrungen oder um neue Ideen oder Denkanstöße zu bekommen.

Continous Deployment

Was die Überschrift Continous Deployment hatte und wohl anfänglich eher die Intention hatte, thematisch in Richtung Rollout zu gehen und vielleicht auch darin, die Admins mit ins Boot zu holen, führte initial dazu, dass wir uns ziemlich lange daran aufhielten zu klären, welche Tools für Projektverwaltung, Issuetracking, Testing und Continous Integration in Verwendung sind und was die einzelnen Schmerzen in der Verwendung oder auch deren Vorteile sind. Ich denke, in den letzen 10 Minuten sind wir dann auch endlich zum eigentlichen Thema gekommen.

Ich für meinen Teil konnte mitnehmen, dass meine bisher gewählte Tooling-Landschaft ganz gut ist und dass es offenbar noch keine wirkliche Patentlösung über den Schritt des "Der CI-Server erstellt ein unitgetestetes Deploymentpakt." hinaus gibt. Ich bin mir auch nicht ganz sicher bis zu welchem Schritt diese gehen könnte, schließlich sind die Anforderungen für eine solche Lösung ziemlich speziell. Schon allein das Deployment im Testszenario ist bei Desktop-Anwendungen, die man auf möglichst vielen Denktop-Betriebssystemversionen testen möchte mit diversen Patchleveln eine ganz andere als bei Webanwendungen, bei denen in der Regel der Server klar ist und hier eher die technologische Hüde steht, den finalen Deploymentstep auf die Produktion mit ggf. notwendigen VPN-Verbindungen technologisch automatisiert zu meistern.

TypeScript, CoffeeScript, Dart

Bisher hatte ich nur einen Blogpost zum Thema TypeScript überflogen und CoffeeScript aufgrund des notwendigen Einarbeitungsaufwandes für das Team auch verworfen. Aus diesem Grund war es thematisch spannend, etwas tiefer in TypeScript eintauchen zu können und zu erfahren, welche anderen Erfahrungen es gibt. Hätte es TypeScript schon vor 3 Jahren gegeben, ich glaube der Einarbeitungsaufwand für mich als Entwickler, der eher aus einer streng typisierten Welt kommt, wäre wesentlich einfacher gewesen - zum einen weil man durch die zugegeben rudimentäre Typisierung mit 3 Datentypen einfacher auf Fallstricke hingewiesen wird, zum anderen weil solche Konstrukte wie Klassen und Konstruktoren auf der TypeScript-Seite so übersichtlich gegenübergestellt sind, dass man schnell versteht, wie die JavaScript-Repäsentation aussieht.

Twitter Bootstrap und UI Frameworks für's Web

Die Funktionalität von Bootstrap verwenden, ohne die Individualität der Webseite zu verlieren? Erprobte UI-Prinzipien verwenden, und trotzdem nicht aussehn wie Twitter? Solche und ähnliche Fragen waren Kern der Session. Es ging darum, ob und wann es sich lohnt, Bootstrap als Basis zu nehmen und hier Anpassungen vorzunehmen oder ob es eher praktikabel ist, ein Gridlayout oder eine leere HTML-Seite zu Basis zu nehmen und darauf aufbauend Funktionalitäten hinzuzufügen. Die Quintessenz: Es kommt darauf an. Ich für meinen Teil bleibe wohl vorerst bei dem bisherigen Verfahren: Wenn der Kunde das Twitter-Layout gut findet und daran nur wenige Anpassungen möchte oder der Fokus mehr auf Funktionalität als auf Individualität liegt, sind Gridsysteme oder Bootstrap eine gute Wahl. Ist eine individuelle Lösung gefragt, dann wird auch individuell entwickelt.

Zum Ende kam noch die Frage hoch nach Sketch- oder UI-Mocking-Tools. Die Antworten überraschten nicht viel: PowerPoint, Sketchflow, Balsamiq, kuler und weitere Altbekannte.

Der Rest von REST

JSON kennt wohl jeder Webentwickler. Und seit ASP.NET MVC 4 und der WebAPI spielt es auch in der .NET-Welt eine entscheidende Rolle. Aber REST geht noch weiter als das was wir alle kennen und was out-of-the-box mit den Tools mitkommt. Welche Punkte überliest man eigentlich gern in der REST-Spezifikation und was hat es mit Hypermedia-Elementen auf sich und wie kann man diese sinnvoll in diesem Kontext verwenden? Welche Möglichkeiten bieten sich durch die Verwendung und welche Vorteile ergeben sich dadurch?

Für mich haben sich hier ein paar Denkanstöße ergeben, die sich aber hauptsächlich darauf beziehen, wie man vorgehen könnte, wenn man mal eine öffentliche API bereitstellen möchte, und weniger eine interne Schnittstelle, die nur für einen einzelnen Client vorgesehen ist.

Big Data

Worum ging es? Hadoop! Wer normalerweise mit relationalen Datenbanken oder NoSQL in überschaubarem Ausmaß zu tun hat, auch für den ist es spannend mal herauszufinden, wie man mit wirklich vielen Daten umgeht. Schon alleine aus diesem Aspekt war ein kleiner Einsteig und zwei, drei Beispiele in Hadoop ganz interessant.

 

Nach den Sessions ist vor dem Bierchen. Und so endete auch dieser Tag mit lockeren Gesprächen in geselliger Runde.

Was mir an Windows 8 gefällt –”Mehrere Live Tiles für App” – Teil 9 von 10

19.10.2012 11:12:16 | Gregor Biswanger

Es gibt unterschiedliche Meinungen über das neue Betriebssystem. Hier möchte ich mit einer kleinen Video-Serie, meine Top 10 Lieblingsfeatures aufzeigen. Weitere interessante Informationen findet ihr auch unter windows8-live.de. Viel Spaß!

 

Was mir an Windows 8 gefällt…

video2brain – WPF 4.5 und Silverlight 5

15.10.2012 12:06:00 | Gregor Biswanger

Die letzten Jahre veröffentlichte ich bereits mehrere DVD´s mit Video-Trainings. Die letzte war zum Thema “WPF 4 und Silverlight 4”. Mit dessen auch eine gute Tat für die Deutsche Krebshilfe e.V. vollbracht werden konnte. So startete ich gemeinsam mit der Community die Aktion “WPF 4 und Silverlight 4 gegen Krebs”. Was aus meiner Sicht ein voller Erfolg war Danke Community! Bitte Deutsche Krebshilfe e.V.).

 

WPF 4.5 & Silverlight 5_klein

 

Aus Liebe der beiden Technologien und der hohen Nachfrage, kann ich heute mit stolz den Nachfolger “WPF 4.5 und Silverlight 5” ankündigen.

 

WPF 4.5 und Silverlight 5 Trailer

 

Offizielle Beschreibung

Mit den aktuellen Programmversionen WPF 4.5 und Silverlight 5 halten viele neue nützliche Features Einzug, die beide Tools für Designer aber auch Entwickler noch attraktiver machen. Die von Ihrem Trainer Gregor Biswanger ausgewählten Beispiele stellen insbesondere diese neuen Funktionalitäten in den Mittelpunkt. Die Windows Presentation Foundation, kurz WPF, bietet die Möglichkeit, Desktop-Anwendungen zu erstellen, deren Benutzeroberflächen erheblich moderner, dynamischer und anwendungsfreundlicher sind, als dies bei den klassischen, auf Windows Forms beruhenden Windows-Anwendungen der Fall war. Dabei wurde auf eine klare Trennung von Code und Layout gelegt. Das Layout lässt sich mithilfe der XML-basierten Sprache XAML (Extensible Application Markup Language) beschreiben. Und was WPF für die Entwicklung von Desktop-Anwendungen bietet, leistet Silverlight für Web-Anwendungen.

Dieses Video-Training vermittelt Ihnen zunächst eine Einführung in die Konzepte von WPF und XAML und zeigt an kleinen Beispielen, wie Sie damit umgehen. Anschließend lernen Sie die verfügbaren Steuerelemente kennen und sehen im Detail, was Sie alles damit machen können. Nachdem Sie die Möglichkeiten von WPF ausführlich an zahlreichen Beispielen erlebt haben, lernen Sie danach Silverlight kennen. Während viele grundlegende Konzepte von WPF auch für Silverlight gelten, gibt es auch eine Reihe von Unterschieden.

 

Weitere Informationen

- Produktübersicht

- Inhaltsverzeichnis

 

Kostenfreie Probevideos

 

Einführung in XAML

 

Das Label-Steuerelement

 

Auf Amazon ab sofort erhältlich

 

Verlosung bis zum 29. Oktober 2012

Mit ein bisschen Glück kann man hier auch eine DVD kostenlos abstauben. Einfach ein formloses Kommentar schreiben, obwohl mich Feedback zum Blog allgemein immer interessiert. Teilnahmeschluss ist Montag der 29.10.2012. Bitte die E-Mail-Adresse nicht vergessen (wird aber nicht öffentlich angezeigt), mehr nicht - den Rest klären wir dann per E-Mail im Fall dessen. Der Rechtsweg ist ausgeschlossen. Je Gewinnspiel-Teilnehmer ist eine Einsendung zulässig. Mehrfach-Einsendungen eines Teilnehmers werden nicht berücksichtigt. Die Gewinner werden unter allen Einsendern durch eine Ziehung ermittelt. Eine Ausbezahlung der Preise in bar ist nicht möglich. Ich übernehme keine Haftung für verloren gegangene, beschädigte, fehlgeleitete oder verspätete Teilnahmen sowie für irgendwelche technische Schwierigkeiten.

 

Besten Dank

Besten Dank an das ganze video2brain-Team und an Addison-Wesley!

video2brain-logo addison-wesley

Was mir an Windows 8 gefällt –”Semantic Zoom” – Teil 8 von 10

15.10.2012 09:24:58 | Gregor Biswanger

Es gibt unterschiedliche Meinungen über das neue Betriebssystem. Hier möchte ich mit einer kleinen Video-Serie, meine Top 10 Lieblingsfeatures aufzeigen. Weitere interessante Informationen findet ihr auch unter windows8-live.de. Viel Spaß!

 

Was mir an Windows 8 gefällt…

DNUG Braunschweig - Visual Studio 2012 Launch Event + MS Office & Kinect Entwicklung

15.10.2012 02:05:00 | Lars Keller

Die DNUG Braunschweig trifft sich am 17.10.2012 um 19:00 im Restaurant Zucker (Tagungsraum). Dieses Mal feiern wir den Visual Studio 2012 Launch, lasst Euch überraschen! Des Weiteren werde ich einen Vortrag zur MS Office & Kinect – Entwicklung halten.

Abstract: Neue Wege der Benutzerinteraktion: Kinect & MS Office

Durch Kinect stehen (nicht nur) dem Entwickler viele neue Möglichkeiten der Benutzerinteraktion offen. Gerade erst wurde eine neue Version des Kinect SDKs veröffentlicht! In dieser Session tauchen wir in das Kinect SDK ein und schauen uns an, wie wir dies z.B. mit MS Office nutzen könnten. Eines verspricht dieser Vortrag mit Garantie, es wird eine Benutzerinteraktion geben!

Wie immer ist die Veranstaltung kostenlos! Weitere Informationen zur DNUG Braunschweig können hier gefunden werden: http://www.dotnet-braunschweig.de

In die JSON-Serialisierung eingreifen

05.10.2012 19:11:00 | Martin Hey

Der Anwendungsfall

In einer Seite sollen Diagramme angezeigt werden. Für die Darstellung habe ich mich für flot entschieden. Dabei handelt es sich um eine JavaScript-Bibliothek, die in einem Platzhalter mit Hilfe von Canvas-Elementen Charts in diversen Formaten zeichnen kann. 

Im ersten Beispiel soll ein Tortendiagramm erzeugt werden. 

Die Datenstruktur ist dabei recht simpel. Es handelt sich um ein Array von Objekten mit jeweils einem Label und einem Zahlenwert für die Daten.

var pieData = [{ label: "geschieden", data: 5 }, { label: "verheiratet", data: 25 }, { label: "ledig", data: 30 }];
$.plot($("#myChart"), pieData, {
    series: {
        pie: {
            show: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

Im zweiten Beispiel soll ein Liniendiagramm erzeugt werden, das Werte mehrerer Serien über einen Zeitraum darstellen kann.

Die Datenstruktur ist ähnlich wie die des Tortendiagramms. Nur nun enthält data nicht mehr einen einzelnen Wert, sondern ein Array von x-y-Werten. das Beispiel beinhaltet die Daten vom 01.11. bis 03.11.2012. Die x-Achse ist auf den Zeitraum 31.10. bis 04.11. arretiert, damit der erste Datenwert nicht direkt am Rand des Charts liegt.

var lineData = [
    { label: "aktive Kunden", data: [[1351724400000, 213], [1351810800000, 215], [1351897200000, 217]] },
    { label: "Support Tickets", data: [[1351724400000, 100], [1351810800000, 80], [1351897200000, 70]] }
];
$.plot($("#myChart"), lineData, {
    xaxis: {
        mode: "time",
        min: new Date(2012, 09, 31).getTime(),
        max: new Date(2012, 10, 4).getTime(),
    },
    yaxis: {
        tickDecimals: 0,
        min: 0,
        max: 300
    },
    series: {
        lines: { show: true },
        points: {
            radius: 3,
            show: true,
            fill: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

So weit so gut.

Daten dynamisch laden

Nun sind solche Daten ja nicht immer fix, sondern sie sollen nach Möglichkeit asynchron vom Server geholt werden. Schaut man sich die Datenstruktur an, so erkennt man, dass es sich hier um Json handelt. Der Schluss liegt also nahe, dass man sich einfach eine Controller-Action erzeugt, die das entsprechende Format zurückliefert. Json aus einer ASP.NET MVC Anwendung zu erzeugen ist im Grunde recht einfach, gibt es doch JsonResult und die zugehörige Controller-Funktion Json in verschiedenen Überladungen, der man einfach ein Objekt übergibt, welches dann serialisiert wird. Dieses Objekt kann auch ein anonymes Objekt sein. Leider haben anonyme Objekte ein paar Nachteile. Aus diesem Grund soll im weiteren Verlauf in .NET mit konkreten Typen gearbeitet werden.

Das Objekt für das Tortendiagramm ist etwas simpler. Aus diesem Grund soll dieses zuerst erzeugt werden. Benötigt wird eine Auflistung an Objekten, die über die Eigenschaft Label und Data verfügen. 

Schritt 1 ist daher die Definition eines solchen Objektes:

public class PieChartSeries
{
    public string Label { get; set; }
    public double Data { get; set; }
}

Schritt 2 ist die Ausgabe einer Auflistung dieser Objekte in einem JsonResult:

public JsonResult ChartData()
{
    var data = new[]
        {
            new PieChartSeries { Label = "verheiratet", Data = 20 },
            new PieChartSeries { Label = "geschieden",  Data =5 },
            new PieChartSeries { Label = "ledig", Data = 25 }
        };

    return this.Json(data, JsonRequestBehavior.AllowGet);
}

Leider stellt sich nun schon erste Ernüchterung ein. In .NET sind Eigenschaften Pascal Case, im JavaScript sind sie klein geschrieben. Der Serializer der im JsonResult zum Zuge kommt nimmt jedoch logischerweise die Schreibweise der .NET-Properties. Um etwas vorzugreifen: Bei der Zeitachse für das Linienchart kommt es zu einem weiteren Problem. flot benötigt die Daten als JavaScript-Timestamp - also den 01.11.2012 als 1351724400000. Der Serializer serialisiert jedoch ein konkretes Datum im Format Date(1351724400). Beides bedeutet, dass man zwar den Standard JavaScriptSerializer im JsonResult verwenden kann, im Anschluss aber im JavaScript selbst noch einige "Umbauten" vornehmen muss, um diese Daten auch verwenden zu können.

JavaScriptConverter helfen

JsonResult verwendet einen JavaScriptSerializer zur Serialisierung und Deserialisierung der Objekte. Und dieser Serializer verfügt über eine Eigenschaft CustomConverters. Hier kann in die Konvertierung eingegriffen werden. Leider verfügt aber JsonResult über keine Möglichkeit, diese Converter mitzugeben. Daher bleibt nur eine Lösung: Es wird auch noch eine Ableitung von JsonResult benötigt.

Schritt 1: der PieSeriesConverter

Der PieSeriesConverter ist nicht sehr kompliziert, da die Ausgabe schon sehr nah am Soll ist. Lediglich die Eigenschaftsnamen müssen klein geschrieben werden.

public class ChartSeriesJavaScriptConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(PieChartSeries) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotSupportedException("deserializing is not supported");
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var properties = GetPublicReadWriteProperties(obj.GetType());
        var result = new Dictionary<string, object>();

        foreach (var property in properties)
        {
            var key = property.Name.ToLowerInvariant();
            var value = property.GetValue(obj, null);
            result.Add(key, value);
        }

        return result;
    }

    private static IEnumerable<PropertyInfo> GetPublicReadWriteProperties(IReflect type)
    {
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(t => t.CanRead && t.CanWrite)
            .Where(t => t.GetGetMethod(true).IsPublic)
            .Where(t => t.GetSetMethod(true).IsPublic);

        return properties.ToList();
    }
}

Der Einfachheit halber wird die Deserialisierung dieser Objekte vorerst nicht unterstützt.

Schritt 2: ein neues JsonResult

Es wird ein neues JsonResult benötigt, in das der eben erstellte Converter injiziert werden kann.

public class CustomJsonResult : JsonResult
{
    public IEnumerable<JavaScriptConverter> CustomConverters { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        /* TODO: check for property and parameter validity */

        var response = context.HttpContext.Response;
        response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
        response.ContentEncoding = this.ContentEncoding;
           
        var scriptSerializer = new JavaScriptSerializer();
        scriptSerializer.MaxJsonLength = this.MaxJsonLength.Value;
        scriptSerializer.RecursionLimit = this.RecursionLimit.Value;
            
        if (this.CustomConverters != null)
        {
            scriptSerializer.RegisterConverters(this.CustomConverters);
        }

        response.Write(scriptSerializer.Serialize(this.Data));
    }
}

In der Standardimplementierung werden hier noch die JsonRequestBehavior und sämtliche Eigenschaften und Parameter abgeprüft. Der Übersichtlichkeit wegen verzichte ich im Beispiel darauf. Damit der weitere Code läuft, müssen aber zumindest die Null-Checks implementiert werden. Wichtig ist zudem der Aufruf von RegisterConverters, mit dem nun alle übergebenen Converter an den Serializer weitergegeben werden.

Schritt 3: Anbinden

Fehlt nur noch die Controller-Action und die Anbindung in der View.

public JsonResult ChartData()
{
    var data = new[]
    {
        new PieChartSeries { Label = "verheiratet", Data = 20 },
        new PieChartSeries { Label = "geschieden",  Data =5 },
        new PieChartSeries { Label = "ledig", Data = 25 }
    };

    return new CustomJsonResult
    {
        Data = data,
        CustomConverters = new[] { new ChartSeriesJavaScriptConverter() },
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}
$.getJSON("@Url.Action("ChartData")", function (result) {
    $.plot($("#myChart"), result, {
        series: {
            pie: {
                show: true
            }
        },
        grid: {
            hoverable: true
        },
        legend: {
            labelBoxBorderColor: "none"
        }
    });
});

Erweiterung für das Zeitdiagramm

Für das Liniendiagramm mit Zeitachse muss das Beispiel noch etwas erweitert werden, da die Datenstruktur hier ja etwas anders ist. Die grundlegende Herangehensweise ist aber ähnlich. Es wird ein neues Datenobjekt und ein dazu passender Converter benötigt.

Schritt 1: Erstellen eines Datenobjektes

public class DateTimeLineChartSeries
{
    public DateTimeLineChartSeries(string label, Dictionary<DateTime, double> data)
    {
        this.Label = label;
        this.Data = data;
    }

    public string Label { get; set; }

    public Dictionary<DateTime, double> Data { get; set; }
}

Schritt 2: Erstellen des Converters

public class DateTimeLineSeriesConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(DateTimeLineChartSeries) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotSupportedException("deserializing is not supported");
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var properties = GetPublicReadWriteProperties(obj.GetType());
        var result = new Dictionary<string, object>();

        foreach (var property in properties)
        {
            var key = property.Name.ToLowerInvariant();
            var value = property.GetValue(obj, null);


            if (property.Name.Equals("Data", StringComparison.OrdinalIgnoreCase))
            {
                double[][] values = null;

                var dateTimeChartSeries = obj as DateTimeLineChartSeries;
                if (dateTimeChartSeries != null)
                {
                    values = dateTimeChartSeries.Data.Select(x => new[] { GetUnixTimestamp(x.Key) * 1000, x.Value }).ToArray();
                }

                if (values != null)
                {
                    result.Add(key, values);
                }

                continue;
            }

            result.Add(key, value);
        }

        return result;
    }

    private static double GetUnixTimestamp(DateTime value)
    {
        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        var span = value - epoch;
        var unixTime = span.TotalSeconds;
        return unixTime;
    }

    private static IEnumerable<PropertyInfo> GetPublicReadWriteProperties(IReflect type)
    {
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(t => t.CanRead && t.CanWrite)
            .Where(t => t.GetGetMethod(true).IsPublic)
            .Where(t => t.GetSetMethod(true).IsPublic);

        return properties.ToList();
    }
}

Wichtig hier ist, dass die Datumswerte in das JavaScript-Timestamp-Format überführt werden. Dabei handelt es sich um den Unix-Timstamp des DateTime-Wertes, multipliziert mit 1000. Wenn man eine solche Umrechnung häufiger braucht, lohnt sich eine Extension-Method auf DateTime.

Schritt 3: Anbinden

Das Anbinden erfolgt wieder ähnlich zum Tortendiegramm.

public JsonResult ChartData()
{
    var data = new[]
    {
        new DateTimeLineChartSeries(
            "aktive Kunden", 
            new Dictionary<DateTime, double>
                {
                    { new DateTime(2012,11,1), 170 },
                    { new DateTime(2012,11,2), 180 },
                    { new DateTime(2012,11,3), 220 }
                }),
        new DateTimeLineChartSeries(
            "Support-Tickets", 
            new Dictionary<DateTime, double>
                {
                    { new DateTime(2012,11,1), 100 },
                    { new DateTime(2012,11,2), 80 },
                    { new DateTime(2012,11,3), 75 }
                })
    };

    return new CustomJsonResult
    {
        Data = data,
        CustomConverters = new[] { new DateTimeLineSeriesConverter() },
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}
$.getJSON("@Url.Action("ChartData")", function (result) {
    $.plot($("#myChart"), result, {
        xaxis: {
            mode: "time",
            min: new Date(2012, 09, 31).getTime(),
            max: new Date(2012, 10, 4).getTime(),
        },
        yaxis: {
            tickDecimals: 0,
            min: 0,
            max: 300
        },
        series: {
            lines: { show: true },
            points: {
                radius: 3,
                show: true,
                fill: true
            }
        },
        grid: {
            hoverable: true
        },
        legend: {
            labelBoxBorderColor: "none"
        }
    });
});

In der Realität würde man nun noch die Diagrammgrenzen automatisiert bestimmen und vielleicht auch noch die Achsenbeschriftung anpassen. Aber darum geht es an dieser Stelle nicht mehr.

Da es sich hierbei nur um darzustellende Werte handelt, ist auf den Weg der Deserialisierung nicht näher eingegangen worden. Da die Eigenschaftsnamen verändert wurden, wäre auch das eine kleine Herausforderung. Wenn es sich also um Datenobjekte handelt, die auch wieder im .NET eingelesen werden müssen, sollte man speziell auf diesen Schritt verzichten und eine andere Lösung suchen.

Trotz alledem zeigt dieser Post ganz gut, wie man mit wenigen Eingriffen die .NET-Welt und die JavaScript-Welt synchronisieren kann.

In die JSON-Serialisierung eingreifen

05.10.2012 19:11:00 | Martin Hey

Der Anwendungsfall

In einer Seite sollen Diagramme angezeigt werden. Für die Darstellung habe ich mich für flot entschieden. Dabei handelt es sich um eine JavaScript-Bibliothek, die in einem Platzhalter mit Hilfe von Canvas-Elementen Charts in diversen Formaten zeichnen kann. 

Im ersten Beispiel soll ein Tortendiagramm erzeugt werden. 

Die Datenstruktur ist dabei recht simpel. Es handelt sich um ein Array von Objekten mit jeweils einem Label und einem Zahlenwert für die Daten.

var pieData = [{ label: "geschieden", data: 5 }, { label: "verheiratet", data: 25 }, { label: "ledig", data: 30 }];
$.plot($("#myChart"), pieData, {
    series: {
        pie: {
            show: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

Im zweiten Beispiel soll ein Liniendiagramm erzeugt werden, das Werte mehrerer Serien über einen Zeitraum darstellen kann.

Die Datenstruktur ist ähnlich wie die des Tortendiagramms. Nur nun enthält data nicht mehr einen einzelnen Wert, sondern ein Array von x-y-Werten. das Beispiel beinhaltet die Daten vom 01.11. bis 03.11.2012. Die x-Achse ist auf den Zeitraum 31.10. bis 04.11. arretiert, damit der erste Datenwert nicht direkt am Rand des Charts liegt.

var lineData = [
    { label: "aktive Kunden", data: [[1351724400000, 213], [1351810800000, 215], [1351897200000, 217]] },
    { label: "Support Tickets", data: [[1351724400000, 100], [1351810800000, 80], [1351897200000, 70]] }
];
$.plot($("#myChart"), lineData, {
    xaxis: {
        mode: "time",
        min: new Date(2012, 09, 31).getTime(),
        max: new Date(2012, 10, 4).getTime(),
    },
    yaxis: {
        tickDecimals: 0,
        min: 0,
        max: 300
    },
    series: {
        lines: { show: true },
        points: {
            radius: 3,
            show: true,
            fill: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

So weit so gut.

Daten dynamisch laden

Nun sind solche Daten ja nicht immer fix, sondern sie sollen nach Möglichkeit asynchron vom Server geholt werden. Schaut man sich die Datenstruktur an, so erkennt man, dass es sich hier um Json handelt. Der Schluss liegt also nahe, dass man sich einfach eine Controller-Action erzeugt, die das entsprechende Format zurückliefert. Json aus einer ASP.NET MVC Anwendung zu erzeugen ist im Grunde recht einfach, gibt es doch JsonResult und die zugehörige Controller-Funktion Json in verschiedenen Überladungen, der man einfach ein Objekt übergibt, welches dann serialisiert wird. Dieses Objekt kann auch ein anonymes Objekt sein. Leider haben anonyme Objekte ein paar Nachteile. Aus diesem Grund soll im weiteren Verlauf in .NET mit konkreten Typen gearbeitet werden.

Das Objekt für das Tortendiagramm ist etwas simpler. Aus diesem Grund soll dieses zuerst erzeugt werden. Benötigt wird eine Auflistung an Objekten, die über die Eigenschaft Label und Data verfügen. 

Schritt 1 ist daher die Definition eines solchen Objektes:

public class PieChartSeries
{
    public string Label { get; set; }
    public double Data { get; set; }
}

Schritt 2 ist die Ausgabe einer Auflistung dieser Objekte in einem JsonResult:

public JsonResult ChartData()
{
    var data = new[]
        {
            new PieChartSeries { Label = "verheiratet", Data = 20 },
            new PieChartSeries { Label = "geschieden",  Data =5 },
            new PieChartSeries { Label = "ledig", Data = 25 }
        };

    return this.Json(data, JsonRequestBehavior.AllowGet);
}

Leider stellt sich nun schon erste Ernüchterung ein. In .NET sind Eigenschaften Pascal Case, im JavaScript sind sie klein geschrieben. Der Serializer der im JsonResult zum Zuge kommt nimmt jedoch logischerweise die Schreibweise der .NET-Properties. Um etwas vorzugreifen: Bei der Zeitachse für das Linienchart kommt es zu einem weiteren Problem. flot benötigt die Daten als JavaScript-Timestamp - also den 01.11.2012 als 1351724400000. Der Serializer serialisiert jedoch ein konkretes Datum im Format Date(1351724400). Beides bedeutet, dass man zwar den Standard JavaScriptSerializer im JsonResult verwenden kann, im Anschluss aber im JavaScript selbst noch einige "Umbauten" vornehmen muss, um diese Daten auch verwenden zu können.

JavaScriptConverter helfen

JsonResult verwendet einen JavaScriptSerializer zur Serialisierung und Deserialisierung der Objekte. Und dieser Serializer verfügt über eine Eigenschaft CustomConverters. Hier kann in die Konvertierung eingegriffen werden. Leider verfügt aber JsonResult über keine Möglichkeit, diese Converter mitzugeben. Daher bleibt nur eine Lösung: Es wird auch noch eine Ableitung von JsonResult benötigt.

Schritt 1: der PieSeriesConverter

Der PieSeriesConverter ist nicht sehr kompliziert, da die Ausgabe schon sehr nah am Soll ist. Lediglich die Eigenschaftsnamen müssen klein geschrieben werden.

public class ChartSeriesJavaScriptConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(PieChartSeries) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotSupportedException("deserializing is not supported");
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var properties = GetPublicReadWriteProperties(obj.GetType());
        var result = new Dictionary<string, object>();

        foreach (var property in properties)
        {
            var key = property.Name.ToLowerInvariant();
            var value = property.GetValue(obj, null);
            result.Add(key, value);
        }

        return result;
    }

    private static IEnumerable<PropertyInfo> GetPublicReadWriteProperties(IReflect type)
    {
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(t => t.CanRead && t.CanWrite)
            .Where(t => t.GetGetMethod(true).IsPublic)
            .Where(t => t.GetSetMethod(true).IsPublic);

        return properties.ToList();
    }
}

Der Einfachheit halber wird die Deserialisierung dieser Objekte vorerst nicht unterstützt.

Schritt 2: ein neues JsonResult

Es wird ein neues JsonResult benötigt, in das der eben erstellte Converter injiziert werden kann.

public class CustomJsonResult : JsonResult
{
    public IEnumerable<JavaScriptConverter> CustomConverters { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        /* TODO: check for property and parameter validity */

        var response = context.HttpContext.Response;
        response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
        response.ContentEncoding = this.ContentEncoding;
           
        var scriptSerializer = new JavaScriptSerializer();
        scriptSerializer.MaxJsonLength = this.MaxJsonLength.Value;
        scriptSerializer.RecursionLimit = this.RecursionLimit.Value;
            
        if (this.CustomConverters != null)
        {
            scriptSerializer.RegisterConverters(this.CustomConverters);
        }

        response.Write(scriptSerializer.Serialize(this.Data));
    }
}

In der Standardimplementierung werden hier noch die JsonRequestBehavior und sämtliche Eigenschaften und Parameter abgeprüft. Der Übersichtlichkeit wegen verzichte ich im Beispiel darauf. Damit der weitere Code läuft, müssen aber zumindest die Null-Checks implementiert werden. Wichtig ist zudem der Aufruf von RegisterConverters, mit dem nun alle übergebenen Converter an den Serializer weitergegeben werden.

Schritt 3: Anbinden

Fehlt nur noch die Controller-Action und die Anbindung in der View.

public JsonResult ChartData()
{
    var data = new[]
    {
        new PieChartSeries { Label = "verheiratet", Data = 20 },
        new PieChartSeries { Label = "geschieden",  Data =5 },
        new PieChartSeries { Label = "ledig", Data = 25 }
    };

    return new CustomJsonResult
    {
        Data = data,
        CustomConverters = new[] { new ChartSeriesJavaScriptConverter() },
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}
$.getJSON("@Url.Action("ChartData")", function (result) {
    $.plot($("#myChart"), result, {
        series: {
            pie: {
                show: true
            }
        },
        grid: {
            hoverable: true
        },
        legend: {
            labelBoxBorderColor: "none"
        }
    });
});

Erweiterung für das Zeitdiagramm

Für das Liniendiagramm mit Zeitachse muss das Beispiel noch etwas erweitert werden, da die Datenstruktur hier ja etwas anders ist. Die grundlegende Herangehensweise ist aber ähnlich. Es wird ein neues Datenobjekt und ein dazu passender Converter benötigt.

Schritt 1: Erstellen eines Datenobjektes

public class DateTimeLineChartSeries
{
    public DateTimeLineChartSeries(string label, Dictionary<DateTime, double> data)
    {
        this.Label = label;
        this.Data = data;
    }

    public string Label { get; set; }

    public Dictionary<DateTime, double> Data { get; set; }
}

Schritt 2: Erstellen des Converters

public class DateTimeLineSeriesConverter : JavaScriptConverter
{
    public override IEnumerable<Type> SupportedTypes
    {
        get
        {
            return new[] { typeof(DateTimeLineChartSeries) };
        }
    }

    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        throw new NotSupportedException("deserializing is not supported");
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        var properties = GetPublicReadWriteProperties(obj.GetType());
        var result = new Dictionary<string, object>();

        foreach (var property in properties)
        {
            var key = property.Name.ToLowerInvariant();
            var value = property.GetValue(obj, null);


            if (property.Name.Equals("Data", StringComparison.OrdinalIgnoreCase))
            {
                double[][] values = null;

                var dateTimeChartSeries = obj as DateTimeLineChartSeries;
                if (dateTimeChartSeries != null)
                {
                    values = dateTimeChartSeries.Data.Select(x => new[] { GetUnixTimestamp(x.Key) * 1000, x.Value }).ToArray();
                }

                if (values != null)
                {
                    result.Add(key, values);
                }

                continue;
            }

            result.Add(key, value);
        }

        return result;
    }

    private static double GetUnixTimestamp(DateTime value)
    {
        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        var span = value - epoch;
        var unixTime = span.TotalSeconds;
        return unixTime;
    }

    private static IEnumerable<PropertyInfo> GetPublicReadWriteProperties(IReflect type)
    {
        var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .Where(t => t.CanRead && t.CanWrite)
            .Where(t => t.GetGetMethod(true).IsPublic)
            .Where(t => t.GetSetMethod(true).IsPublic);

        return properties.ToList();
    }
}

Wichtig hier ist, dass die Datumswerte in das JavaScript-Timestamp-Format überführt werden. Dabei handelt es sich um den Unix-Timstamp des DateTime-Wertes, multipliziert mit 1000. Wenn man eine solche Umrechnung häufiger braucht, lohnt sich eine Extension-Method auf DateTime.

Schritt 3: Anbinden

Das Anbinden erfolgt wieder ähnlich zum Tortendiegramm.

public JsonResult ChartData()
{
    var data = new[]
    {
        new DateTimeLineChartSeries(
            "aktive Kunden", 
            new Dictionary<DateTime, double>
                {
                    { new DateTime(2012,11,1), 170 },
                    { new DateTime(2012,11,2), 180 },
                    { new DateTime(2012,11,3), 220 }
                }),
        new DateTimeLineChartSeries(
            "Support-Tickets", 
            new Dictionary<DateTime, double>
                {
                    { new DateTime(2012,11,1), 100 },
                    { new DateTime(2012,11,2), 80 },
                    { new DateTime(2012,11,3), 75 }
                })
    };

    return new CustomJsonResult
    {
        Data = data,
        CustomConverters = new[] { new DateTimeLineSeriesConverter() },
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}
$.getJSON("@Url.Action("ChartData")", function (result) {
    $.plot($("#myChart"), result, {
        xaxis: {
            mode: "time",
            min: new Date(2012, 09, 31).getTime(),
            max: new Date(2012, 10, 4).getTime(),
        },
        yaxis: {
            tickDecimals: 0,
            min: 0,
            max: 300
        },
        series: {
            lines: { show: true },
            points: {
                radius: 3,
                show: true,
                fill: true
            }
        },
        grid: {
            hoverable: true
        },
        legend: {
            labelBoxBorderColor: "none"
        }
    });
});

In der Realität würde man nun noch die Diagrammgrenzen automatisiert bestimmen und vielleicht auch noch die Achsenbeschriftung anpassen. Aber darum geht es an dieser Stelle nicht mehr.

Da es sich hierbei nur um darzustellende Werte handelt, ist auf den Weg der Deserialisierung nicht näher eingegangen worden. Da die Eigenschaftsnamen verändert wurden, wäre auch das eine kleine Herausforderung. Wenn es sich also um Datenobjekte handelt, die auch wieder im .NET eingelesen werden müssen, sollte man speziell auf diesen Schritt verzichten und eine andere Lösung suchen.

Trotz alledem zeigt dieser Post ganz gut, wie man mit wenigen Eingriffen die .NET-Welt und die JavaScript-Welt synchronisieren kann.

INETA Deutschland hat eine neue Webseite

02.10.2012 01:42:00 | Lars Keller

Es ist geschafft! Nach einigen Feedback-Runden und Neuanfängen startet ab heute der neue Internetauftritt der INETA Deutschland. Er ist für die Community und aus der Community heraus entstanden. Stellvertretend für die INETA Deutschland haben Karim und ich uns dazu seit dem CLIP-/MVP-Treffen auf der CeBIT 2012 mit vielen aus der Community unterhalten und Feedback eingeholt. Natürlich haben wir auch mit bestehenden und potenziellen Sponsoren gesprochen. Als besonders wichtig wurde immer wieder herausgestellt, dass der Blick hinter die Kulissen der INETA Deutschland geschärft werden sollte.INETA Deutschland Webseite
Das haben wir aufgenommen und präsentieren die rund 10-jährige Community-Arbeit der INETA Deutschland und die Unterstützung von .NET User Groups transparenter. Die neue Webseite bietet dazu unter anderem den Bereich „Sprecherbüro“, Dort werden alle Sprecher aufgelistet, die für Vorträge bei den INETA Deutschland User Groups kostenlos zur Verfügung stehen. Wie Betreiber einer .NET User Group diese bei der INETA Deutschland anmelden können und welche Unterstützung über die INETA Deutschland zur Verfügung steht, wird im Bereich „User Groups“ thematisiert. Interessierte Teilnehmer und mögliche Sponsoren finden in diesem Bereich auf einer User-Group-Map alle der INETA Deutschland angeschlossenen User Groups. Aktuelles zu Events der INETA Deutschland User Groups und der Arbeit von Karim und mir können Interessierte des Weiteren ab sofort über @ineta_de bei Twitter verfolgen und mit uns in Kontakt treten.

Logos
Im Rahmen der Überarbeitung unserer Webseite haben wir Logos erstellt, mit denen Betreiber einer INETA Deutschland User Group oder Sprecher ihre Zugehörigkeit zur INETA Deutschland präsentieren können.

Logos der INETA Deutschland

Wie geht es weiter
In der nächsten Zeit werden wir unseren Internetauftritt weiter „schärfen“ und fehlende Informationen ergänzen. Ein weiteres Anliegen ist es, die Position der INETA Deutschland als Anlaufstelle für mögliche Sponsoren zu festigen! Hierzu werden wir ebenfalls noch mehr Informationen bereitstellen und weitere Gespräche mit möglichen Sponsoren führen.

Aufruf an die DNUG Community
Ich würde gern die aktuellen Fotos auf der Startseite durch Fotos von User Group Treffen ersetzen. Daher der Aufruf an alle INETA Deutschland User Groups, schickt uns bitte ein Foto. Gern auch mit einer kleinen Beschreibung (1-2 Sätze), dann bauen wir beides zusammen ein.
Der zweite Aufruf geht an alle Sprecher des Sprecherbüros. Schaut Eure Themen und Informationen durch und schickt mir dazu bitte ein Update. Wir pflegen dies dann gern ein.

Dankeschön!
Karim und ich möchten uns ganz herzlich bei Torsten Weber (DNUG Leipzig) bedanken, welcher uns sehr bei der Erstellung des neuen Designs unterstützt hat! Community rockt! :-)
Bleibt abschließend noch zu erwähnen, dass wir Feedback gerne entgegennehmen.

Regeln | Impressum