codefest.at [MS]: Free Developer Notebook Stickers

Bist du Developer? Ja? Fein, dann hab ich da einen raschen Tipp (für uns Geeks): Order your FREE Dev Stickers!

Auf der Website https://stickers.onion.io/ können Developer 3 Kleber bestellen:

image

Es ist nur ein Login von GitHub und eine App-Berechtigung erforderlich.

Mal sehen obs klappt! Winking smile

codefest.at [MS]: Azure Logic Apps sind da

In Microsoft Azure kommen fast täglich Neuigkeiten hinzu, die Cloud machts möglich. Ein relativ neues Service darin sind die Azure Logic Apps. Diese wurden im Mai 2016 bei der Integrate 2016 conference in London vorgestellt. Nun sind die Azure Logic Apps allgemein verfügbar (GA).

Azure Logic Apps stellen eine Infrastruktur bereit, die einen Dataflow aus nahezu beliebigen Datenquellen in andere Systemen ermöglichen und zwar für Power Users und Developer, in Cloud und in Hybrid-Szenarien. Einerseits unterstützt ein Designer bei der Definition des Dataflows und andrerseits können Logic Apps customized und erweitert werden. Nicht umsonst basieren Logic Apps auf BizTalk Server Logik. Azure Logic Apps könnte man als eine Art Biztalk kombiniert mit IfThisThanThat verstehen, schön verpackt als Cloud-Service.

Der Startpunkt für Azure Logic Apps ist unter Azure.com – oder in der eigenen Azure Subscription.

image

Seit Ende Juli sind die Azure Logic Apps nun allgemein verfügbar (general availability), schreibt Frank Weigel, Principal Director Program Management, im Azure Blog:

Announcing Azure Logic Apps general availability

Der Dataflow kann im Designer modelliert werden, wie etwa in diesem Beispiel aus der Ankündigung.

image

Wichtig hierbei sind natürlich die “Connectors”, welche für verschiedenste Systeme fertig bereitstehen. Das können öffentliche Interfaces zu Diensten wie CRM Online, Dropbox, Facebook, Twitter, GitHub, Google Drive, FTP und viele mehr sein.

Für Entwickler sind die Logic Apps besonders interessant, da sie auch Daten aus eigenen Web-API Schnittstellen oder etwa direkt von Azure Blob Storage verwenden können. Umgekehrt muss keine eigene Logik für eine Transformation oder Notifications entwickelt werden, sondern dies kann in den Logic Apps erfolgen. Ich sehe das als sehr großen Vorteil gerade in Szenarien, wo Daten aus eigenen Applikationen in andere Systeme fließen sollen – oder umgekehrt.

Für alle jene, die sich mit Logic Apps befassen wollen, empfehle ich die Tutorial: Connect Logic App to your Azure IoT Suite Remote Monitoring preconfigured solution Seite. Hier wird eine Demoapp angelegt, welche Daten aus einer vorkonfigurierten IoT Demosuite verwendet und ein simples Monitoring per SendGrid Dienst bereitstellt. Der Dataflow sieht im Designer etwa wie folgt aus.

image

Dieses IoT-Beispiel demonstriert visuell recht schön, was in diesem Demo passiert: Daten werden aus einer HTTP Schnittstelle geliefert und an eine EMail Adresse per SendGrid versendet. Easy going, oder?

Last but not least, jetzt , wo Azure Logic Apps verfügbar sind, gibt es auch finale Preise dafür. Das Pricing ist sehr überschaubar und abhängig von der Menge der verarbeiteten Daten, siehe hier.

In diesem Sinne: Es gibt sicherlich viele Szenarien, wo Azure Logic Apps eigene Apps und Lösungen unterstützen können und einen stabilen, skalierbaren Cloud-Service anbieten, der sich durch Interfaces leicht konsumieren läßt. Viel Spaß mit Logic Apps!

Marco Scheel: Links for 2016-07-28 [del.icio.us]

Marco Scheel: Links for 2016-07-27 [del.icio.us]

Sven Hubert: Rückblick auf Microsofts Worldwide Partner Conference 2016

Vom 11.07.2016 bis 14.07.2016 lud Microsoft zu seiner alljährlichen Partnerkonferenz (WPC) ein, eine Konferenz, auf der Microsoft seinen Partnern einen Blick in die Zukunft und Stoßrichtung des Unternehmens gibt und auf der Partner die Möglichkeit haben, sich mit Microsoft und anderen Partnern über aktuelle und zukünftige Themen und Zusammenarbeiten zu unterhalten.

Auch auf der WPC 2016 war das über allem schwebende Thema die digitale Transformation. In jeder der drei Key Notes verwiesen die Microsoft-Verantwortlichen auf die seit 2015 formulierte Vision, jede Person und jedes Unternehmen auf dem Planeten zu stärken um mehr zu erreichen.

Microsoft_Mission

Ermöglicht werden soll dies insbesondere durch Microsofts Cloud-Plattform und den darin zur Verfügung stehenden Diensten. Microsoft stellt dabei in besonderem Maße heraus, dass Sicherheit, Compliance, Transparenz und Vertrauen die Basis und das Alleinstellungsmerkmal der Microsoft Cloud sind. Dabei wurde erneut auf die German Cloud verwiesen, ein Konstrukt, bei dem Microsoft nur Technologielieferant ist, die Daten aber von einem deutschen Datentreuhänder verwaltet werden, und somit der Zugriff auf diese Daten durch Dritte vollständig dem deutschen Recht unterliegt. Diese Rechtssicherheit kann heute keiner der Wettbewerber von Microsoft bieten.

Darüber hinaus sieht Microsoft einen Zwang zur Digitalisierung, denn Digitalisierung sei ein Merkmal erfolgreicher Unternehmen. Um dies zu erreichen, sollen drei Bestrebungen verfolgt werden:

  1. Produktivität und Geschäftsprozesse neu definieren
  2. Die intelligente Cloud Plattform liefern
  3. Ein persönlicheres Computer-Erlebnis schaffen

In der Keynote unterhielt sich Satya Nadella mit Jeff Immelt, dem CEO von G.E. darüber, wie dieses 140 Jahre alte Unternehmen die Herausforderung der Digitalisierung angenommen hat. Jeff Immelts Kernaussage in dem Gespräch war: „Wir stehen an einer Grenzlinie für Industrieunternehmen. Es gibt eine Vergangenheit und es wird eine Zukunft geben. Und die Zukunft ist abhängig davon, wer am schnellsten digitalisiert!“ Das ganze Gespräch können sie hier ansehen:



Microsoft stellt auf der WPC auch nochmals ganz klar heraus, dass es ein durch Partner getriebenes Unternehmen ist. Durch Partner werden Technologien und Plattformen zu Lösungen.

Als langjähriger Microsoft-Partner ist für uns bei AIT die WPC ein Gradmesser, inwiefern unser Wissen um Technologien und Methoden dem aus Microsofts Sicht zukünftigen Markt gerecht werden kann. Wir nutzen die Gespräche mit Vertretern von Microsoft und anderen Microsoft-Partnern, um unseren Blick für Lösungen aber auch Engpässe zu schärfen. Darüber hinaus gehen wir noch vor unseren Kunden durch das Tal der Tränen, in dem wir Neuerungen und Empfehlungen selbst ausprobieren und dabei des notwendige Wissen aufbauen, um unseren Kunden die entscheiden Hinweise bei der eigenen Adaption von Technologien und Prozessen zu geben.

Im Kontext der Neudefinition von Geschäftsprozessen und Produktivität baut die Aussage von Microsoft auf dem Einsatz von Office 365, Visual Studio Team Services sowie weiteren Diensten aus der Microsoft Cloud sowie einem mobilen Zugang zu all diesen Informationen. Durch unsere eigene Migration von einer On-Premise Softwarelandschaft hin zu einer hybriden Landschaft, bei der alle führenden Plattformen in der Cloud laufen, können wir aus eigener Erfahrung von sowohl Vorteilen als auch Hindernissen und Nachteilen berichten. Das eine Digitalisierung von Prozessen auch mit fundamentalen Verbesserungen einher geht, zeigt unser Einsatz von PowerBI zur Auswertung unserer Dienstleistungen und Projekte. VSTS nutzen wir seit Preview-Verfügbarkeit des Dienstes und unsere Erweiterungen zur agilen Schätzung und Backlog-Priorisierung zeigen, wie bestehende Dienste um vermisste Funktionen ergänzt werden können. Als Xamarin Premier Consulting Partner können wir zudem unseren Kunden den Weg zur mobilen Anwendung aufzeigen und Sie dabei mit Beratung und Entwicklung erfolgreich begleiten.

Unter dem Begriff der intelligenten Cloud Plattform sieht Microsoft eine Vielzahl an Diensten, die heute bereits in Azure verfügbar sind. Die wichtigsten für unsere Kunden aus dem Maschinen- und Anlagenbau sind sicherlich die als Azure IoT Suite orchestrierte Sammlung von Cloud-Diensten zur Bereitstellung von Szenarien wie Predictive Maintainance oder Remote Monitoring. Microsoft verankert hierzu wie kein anderer Anbieter offene Standards wir OPC UA in seinen Diensten. Darüber hinaus steht, und das war sicher für viele eine überraschende Ankündigung, mit Windows 10 IoT Core ein kostenfreies Betriebssystem für Devices zur Verfügung, welches den gleichen Softwareentwicklungsparadigmen wie die restliche Windows-Plattform folgt und dabei die gleichen Werkzeuge nutzt.



Das persönlichere Computer-Erlebnis heißt bei Microsoft momentan HoloLens. Mit HoloLens realisiert Microsoft eine Vision der Interaktion zwischen Mensch und Computer, die bereits in Science Fiction Filmen des vergangenen Jahrtausends erdacht wurde. Auch wir bei AIT sehen großes Potential insbesondere im industriellen Umfeld für derartige Devices. Gespräche mit unseren Kunden zeigen bereits heute, dass das Interesse und Potential an derartigen Lösungen sehr hoch sind. Wir sind gespannt, welche Ideen wir in diesem Umfeld in Zukunft gemeinsam mit unseren Kunden zum Leben erwecken dürfen. Kontaktieren Sie uns, wenn Sie mehr zu HoloLens, den Möglichkeiten, Bedingungen und Entwicklungen erfahren möchten. Wenn Sie Sich die Microsoft HoloLens live anschauen wollen, dann haben Sie bei unserer Veranstaltung in Stuttgart am 14.9.2016 die Möglichkeit dazu. Melden Sie Sich einfach hier an: AIT HoloLens Roadshow

Als Fazit der WPC nehmen wir mit, dass innovative Softwarelösungen der Schlüssel zur Digitalisierung sein werden und das Softwareentwicklung zur Kompetenz eines jeden Unternehmens gehören wird. Die Beherrschung von Technologien, Prozessen und Werkzeugen werden zum Hygienefaktor einer erfolgreichen Digitalisierungsstrategie und wir freuen uns darauf, unsere Kunden auf diesem Weg führen zu dürfen.

Marco Scheel: Links for 2016-07-25 [del.icio.us]

Sven Hubert: ALM kompakt: TFS entfernt doppelte Work Items beim E-Mail-Versand

Szenario: Man führt eine Work Item Query aus, in der Work Items mehrfach vorkommen. Dies kann beispielsweise der Fall sein, wenn man Backlog Items mit ihren Test Cases ausgeben lässt. Ein Test Case kann sich durchaus auf mehrere Backlog Items beziehen. Nachfolgend ist ein kleiner Ausschnitt eines Backlogs mit zwei User Stories zu sehen. Der Test Case mit der ID 419 kommt in der Liste zweimal vor.

image

Wenn man nun über den im Screenshot hervorgehobenen Mail-Button das Ergebnis der Work Item Query versenden möchte, werden die mehrfach vorkommenden Work Items jeweils nur bei ihrem ersten Vorkommen dargestellt. Die Liste wird also normalisiert. Im konkreten Beispiel sieht dies dann wie folgt aus:

image

Es ist gut zu erkennen, dass unterhalb der User Story 318 der Test Case 419 nicht mehr zu sehen ist. Wenn es darum geht, eine Liste von Work Items zu versenden, die beispielsweise noch durch eine andere Person überarbeitet werden muss, ist dies eine sinnvolle Veränderung der Liste. Möchte man hingegen einem Kollegen oder Kunden die Struktur der Work Items aufzeigen, so möchte man ggf. die vorhandenen, redundanzbehafteten Strukturen unverändert weitergeben. Um dies zu erreichen, gibt es einen kleinen Trick.

Anstatt die Liste wie im ersten Screenshot gezeigt mit dem Button über der Ergebnisliste zu versenden, kann man auch alle Einträge in der Liste markieren. Dies geht am schnellsten über die Tastatur mit <STRG> und A.

image

Über das Kontextmenü (rechte Maustaste) erreicht man dann den Befehl „Copy as HTML“. ACHTUNG: Sehr verlockend ist hier auch der Befehl “Email selected work item(s)…”, dieser führt jedoch auch nicht zu dem gewünschten Ergebnis (siehe weiter unten).

2016-07-25_08-56-21

Es öffnet sich ein Dialog, der eine kopierfreundliche Ansicht zeigt, in der der gewünschte Inhalt bereits ausgewählt ist. Man muss nun nur noch den eigentlichen Kopierbefehl, z.B. mittels <STRG>+C, ausführen. Der Dialog schließt sich danach automatisch wieder.

2016-07-25_09-45-57

Nun kann man den Inhalt direkt in eine E-Mail einbetten, in der dann auch wie gewünscht manche Work Items redundant vorkommen.

2016-07-25_09-46-38

Dieser Weg hat zwar einige manuelle Schritte, geht aber letztlich doch recht flüssig von der Hand. Mit den out-of-the-box Möglichkeiten lässt sich die redundante Abbildung nicht automatisiert per E-Mail versenden.

Für die besonders interessierten Leser nachfolgend noch die Darstellung, wenn man die markierten Elemente mit dem Befehl “Email selected work item(s)…” versendet:

image

Nun wird die komplette Liste in die E-Mail eingefügt, ohne dabei Dubletten zu entfernen. Dies sieht noch so aus, wie man es im eingangs geschilderten Szenario haben möchte.

image

Jedoch kommt beim Empfang die redundanzfreie Form an:

2016-07-25_09-48-10

Wenn man sich in dem anfangs beschriebenen Szenario befindet kann man sich mit ein paar wenigen manuellen Schritten helfen. In vielen anderen Fällen ist die redundanzfreie Darstellung sicherlich hilfreich.

codefest.at [MS]: Visual Studio Code den Run-Button für Websites beibringen

Visual Studio Code ist eine feine Sache. Das kostenlose Entwicklungssystem für Windows, OS X und Linux ist unter https://code.visualstudio.com downloadbar und stellt neben einem sehr leistungsfähigen Editor mit IntelliSense und Debugging, Git-Support und Extensions auch Runtimes für Node.js, .NET Core, Unity und Office bereit. Apropos Runtime: Wie sieht es mit Webprojekten aus? Das müssen wir Visual Studio Code erst beibringen…

Visual Studio Code for all

Für alle jene, die neu in Visual Studio Code (VSC) sind, informiert die Startseite The Basics of Visual Studio Code über den Editor und seine Leistungsfähigkeit.

image

Damit gleich zur Realität…

Wo ist der Run Button?

Gerade, wenn man von Visual Studio kommt, erwartet man einen “Run”-Button und einen gewohnten, ähnlichen Komfort für Webprojekte. Nun, im Gegensatz zu Visual Studio stellt VSC eine “lightweight” Developing-Environment bereit. Es gibt keinen “Run” Button (F5)…

Ein Webprojekt starten

In meinem Beispiel wollte ich ein Office-AddIn für Word bauen und mit VSC bearbeiten. Das Framework habe ich übrigens in Node.js mit npm install -g bower yo generator-office gulp tsd und yo Office erstellt, aber das ist eine andere Geschichte.

Man bearbeitet also ein Webprojekt mit VSC – am besten mit File / Open Folder

image

Nun kann die Bearbeitung erfolgen. Nur, wie sieht man nun den Output? Wie kann man dieses Webprojekt starten…?

image

Klar, man benötigt einen lokalen Webserver. Nur, wie integriert man diesen in VSC?

Command Palette

Zuvor noch einen kleinen Exkurs in VSC: Ein sehr wichtiges Feature in VSC ist die “Command Palette”. Diese ist mit Ctrl+Shift+P (oder am PC schneller mit der F1-Taste) jederzeit erreichbar und bietet Zugriff zur ganzen Funktionalitäten von VSC. In der Anzeige wird nach der Eingabe gefiltert. Wenn verfügbar, wird gleich neben der Funktion die entsprechende Tastenkombination angezeigt. Praktisch und schnell!

image

Gut, Kommandos können also ganz rasch abgesetzt werden. Diese können Formatierungsbefehle oder auch umfangreiche Befehle sein. Das führt uns zu den Erweiterungen…

Extensions

Wer, so wie ich von Visual Studio kommt, sucht hier mal einige Zeit nach einer Methode, das Projekt zu “starten”. Zum Glück gibt es eine einfache Lösung für mein Thema mit dem Webprojekt: Die gute Botschaft ist, dass Visual Studio Code mit sog. “Extensions” erweitert werden kann.

Und es gibt eine ganze Reihe von coolen Extensions für VSC!

image

Die Lösung: IIS Express Extension

Die Integration wird am einfachsten durch eine weitere Extension zu VSC hinzugefügt. Im Visual Studio Marketplace hat Warren Buckley eine Extension für die Integration von IIS Express bereitgestellt. Danke Warren!

IIS Express (Run websites straight from VS Code using IIS Express)

image

Der Code ist übrigens unter https://github.com/warrenbuckley/IIS-Express-Code verfügbar.
(IIS Express – und somit diese Extension - ist nur unter Windows Systemen lauffähig.)

image

Nach der Installation muss die Extension aktiviert werden und VS Code einmal neu gestartet werden.

image

IIS Express Extension verwenden

Nach dem VSC Restart wird der IIS Express (für die Website) gestartet: IIS Express: Run Website. Die Suche nach “run” liefert sogleich die Extension.

image

Nun wird die Website mit dem Start Website Command gestartet.

image

Das Output Window zeigt den Erfolg und die localhost Adresse an (in meinem Beispiel Port 3498).

image

Zusätzlich wird auch sogleich der Default Browser geöffnet. Je nach Projekt-Struktur wird das Default Dokument im Root Folder geöffnet – oder auch nicht…

image

In meinem Beispiel habe ich eine tiefere Ordnerstruktur und ein home.html Startdokument. Somit lautet mein Pfad natürlich http://localhost:3498/app/home/home.html. Damit klappts auch im Browser.

SNAGHTML461a4fd

Der Webserver läuft. Code-Änderungen werden wie erwartet durch Speichern des Files und Refresh im Browser aktualisiert.

Wer den IIS Express Webserver wieder beenden möchte, führt in der Command Palette IIS Express: Run Website und hier den Stop Webserver Befehl aus.

image

Das wars. Die IIS Express Extension bietet eine rasche Methode, Webprojekte mit Visual Studio Code zu entwickeln und zu starten!

Hier noch rasch ein paar Links zu den wichtigsten Themen in VSC:

  • Setup - Install VS Code for your platform and configure the tool set for your development needs.
  • The Basics - Introduction to the basic UI, commands, and features of the VS Code editor.
  • Settings - Customize VS Code for how you like to work.
  • Languages - Learn about VS Code's support for your favorite programming languages.
  • Node.js - This tutorial gets you quickly running and debugging a Node.js web app.
  • Why VS Code? - Read about the design philosophy and architecture of VS Code.
  • Download VS Code - Quickly find the appropriate install for your platform (Windows, OS X and Linux).

Visual Studio Code ist cool! Viel Spaß beim Entwickeln mit VSC!

Marco Scheel: Links for 2016-07-24 [del.icio.us]

codefest.at [MS]: Was ist das neue SharePoint Framework?

Passend zu meinem letzten Blogpost mit dem Hinweis zum Office 365 Developer Podcast möchte ich Software-Entwicklern das neue SharePoint Framework vorstellen. Doch schön der Reihe nach…

Mit der Vorstellung von SharePoint 2016 Anfang Mai (siehe Future of SharePoint) hat Microsoft ein neues Entwicklungsmodell für SharePoint vorgestellt: Das SharePoint Framework. Anstelle von Server-seitigem Development (so, wie es von der ersten SharePoint Version mit ASP und ab 2003 ASP.NET – mit Ausnahme des neuen App Modells - bis heute der Fall war…) tritt nun Client-seitiges Development. Für Entwickler bedeutet das in einem Wort gesagt: Javascript!

Um es auch in Folge sehr kurz zu machen: Mit dem SharePoint Framework ermöglicht Microsoft modernes End-to-End App Development mit Webtechnologien, die nicht von .NET Implementierungen abhängig sind. Das SharePoint Framework wird es für SharePoint Online und SharePoint on premises geben. Es steht derzeit nur als Preview bereit und kann also erst in naher Zukunft eingesetzt werden. Dieser Artikel mit den Ressourcen ist sozusagen als Vorbereitung für Developer zu sehen.

In The SharePoint Framework—an open and connected platform stellt Microsoft das neue Framework kurz vor. Das SharePoint Framework basiert auf Open Source Software und wird auf existierenden SharePoint Sites verfügbar sein. Damit wird Zugriff auf den SP-Presentation Layer, das DOM, Data, Events und den SP-Host möglich sein.

image

Als Startpunkt möchte ich sogleich das Youtube-Video Open and Connected Platform: The SharePoint Framework von Daniel Kogan/Microsoft Mechanics aus dem Artikel mitgeben. In kurzen 15 Minuten erhält man einen Einblick in das neue Framework und das Tooling. Damit sind u.a. moderne und responsive Designs out of the Box möglich.

image

Das Design, die “Page Structure”, besteht aus mehreren Teilen. Footer und Header (der SPO “Seitenrahmen) werden als “Chrome” bezeichnet. Hier fließen Daten, bzw. die Navigation, von der SharePoint-Site ein.

image

Der “Page Body” enthält dann die eigentlichen Daten, den “Canvas” (also die “Leinwand”). Enduser können Inhalte in diesen Canvas (wie zuvor in die WebPart Zones) platzieren. WebParts wiederum können Daten aus SharePoint oder anderen Services wie etwa Office 365 (Exchange, Delve) oder aus eigenen Datenquellen (einer Provider Hosted App) anzeigen.

image

Mit der neuen “Publishing App” können Enduser sehr einfach und intuitiv neue Seiten in SharePoint erstellen.

Für Developer gibt es eine Reihe von Open Source Tools, die zum Einsatz kommen. Die folgende Grafik von http://yeoman.io/ liefert einen Überblick:

image

Der Entwicklungsprozess sieht dann wie folgt aus: Ein Developer erstellt mit Yeoman Scaffolding ein SP-Projekt und entwickelt eine Lösung mit dem SharePoint Framework, etwa mit Visual Studio Code oder mit Visual Studio. Diese wird dann mit eine Build System wie Gulp deployed (siehe u.a. The streaming build system http://gulpjs.com und https://github.com/gulpjs/gulp)

Die folgende Grafik zeigt den Workflow.

image

In dem Beispiel wird die Lösung mit Typescript und den Tools auf Basis von Node.js erstellt. Sobald die Solution gebaut ist, geht es um das Testen und das Deployment.

In dem Prozess gibt es eine für SP-Developer neue Komponente, die SharePoint Workbench. Damit ist ein lokales Testen auch ohne Verbindung zum SharePoint Server möglich – das ist wirklich cool! Der folgende Screenshot zeigt einen Teil der Lösung in Typescript in Visual Studio Code und Node.js mit gulp für das Testen und Deployment.

image

gulp serve erstellt das Deployment-Paket und startet SharePoint Workbench auf dem localhost. Das Webpart verhält sich dabei genauso wie im SharePoint Server. Damit kann das Development losgelöst erfolgen, sogar im Flugzeug… ;). Das Beispiel zeigt ein WebPart mit zwei Image-Größen-Optionen, welches in der SharePoint Workbench läuft.

image

Updates sind integriert: gulp serve läuft im Hintergrund und überwacht Code-Änderungen und re-deployt diese sofort in die SharePoint Workbench. gulp upload-cdn hilft dann beim Packing und Deployment über CDN (eine Vorab-Konfiguration wird hier natürlich vorausgesetzt).

Solche WebParts können nicht nur in Publishing Apps eingefügt werden…

image

…sondern auch via WebPart Editor genauso in existierende Seiten integriert werden. Die WebPart-Eigenschaften können wie gewohnt bearbeitet werden.

image

Ein Hinweis für existierende SharePoint (und Office) Devs und Lösungen…

Keine Sorge, das SharePoint Framework wird das bestehende Modell nicht ersetzen oder ablösen, sondern nur erweitern. Das gesamte Wissen über SharePoint und die APIs kann weiterverwendet werden. Dazu gibt es einen exzellenten Webcast von Vesa Juvonen (Mr. PnP) und Waldek Mastykarz (MVP) in Waldeks’ Artikel SharePoint Framework - powered by open source bzw. direkt auf Channel9.

image

Apropos Office 365 Developer Podcasts: Mehr über das SharePoint Framework gibt es unter anderem in der Episode 093 on PnP and the SharePoint Framework—Office 365 Developer Podcast zu erfahren.

image

Hier sind auch weitere coole Podcasts von Microsoft und Community Kollegen verlinkt.

Für alle Fortgeschrittenen SP-Developer ist auch der Webcast PnP Web Cast - Converting existing JS apps to SharePoint Framework von Vesa Juvonen sehr empfehlenswert sowie die http://dev.office.com/PnP Website.

In diesem Sinne freuen wir uns auf das neue SharePoint Framework und die neuen Funktionen!

codefest.at [MS]: Neues im Office 365 Developer Podcast

Office 365 ist eine Developer Plattform. Als Einstieg in die Entwicklung stellt Microsoft die http://dev.office.com/ Website bereit. Neben den umfangreichen Informationen für den optimalen Start und vielen Demos gibt es auch eine weitere aktuelle Bezugsquelle, die wenig Developern bekannt ist: den Office 365 Developer Podcast. Davon gibt es nun die 100.te Ausgabe!

image

Software-Entwickler finden im Office Dev Center den Einstieg in das Office Development.

Das Office 365 Dev Team bei Microsoft feiert nun den 100.ten Podcast – und zwar mit prominenten Gästen!

Episode 100 with Corporate Vice President Jeff Teper on Future of SharePoint—Office 365 Developer Podcast

image

Hier sprechen Coding-Guru Richard diZerega und Andrew Coates, die Jeff Teper, Corporate Vice President of SharePoint and OneDrive, als Gast begrüßen dürfen. Unter anderem ist auch Jeremy Thake mit dabei, der vorige Produzent des Office 365 Developer Podcasts.

Viel Spaß mit den Podcasts und der Jubiläumsausgabe des Office 365 Developer Podcasts!

Sven Hubert: New release of TFS ASAP for TFS 2015 Update 3

We are proud to present the new release of our TFS Automated Servicing and Administration Platform (TFS ASAP). Besides some minor bug fixes, this version supports update 3 of Microsoft Team Foundation Server 2015. In addition, we improved the usability of the Global Lists Editor.

Administering global lists in TFS is not straight forward. Out of the box, this can only be achieved by using command line or the TFS Power Tools. Both ways require the user to be member of the Project Collection Administrators group. Thus, the number of users who can maintain global lists and their entries are very limited. To remove this limitation TFS ASAP provides the Global Lists Editor, a web based administration platform.

Global List

Within this web page, global lists can be created, updated and deleted. By sorting the global lists and its entries alphabeticaly it should now be easier to find the items you are looking for. New entries are always added on top of the list until the next page load. There is also the option to enable users who are not in the Project Collection Administrators group to maintain global lists by creating a dedicated TFS group. For detailed information about this feature please refer to our user manual (chapter 6).

The installer (Build 14.30.16208.1) can be downloaded here and for further information please visit www.tfsasap.com. If you don’t have a licence key, you can request a trial at support@tfsasap.com.

Marco Scheel: Links for 2016-07-21 [del.icio.us]

  • Object moved
    Last month, we announced an updated approach to the transition of mobile and desktop apps from Visual Studio Application Insights to HockeyApp. To recap that announcement: any existing Mobile and Desktop apps will now have a linked HockeyApp app. via Pocket
  • Microsoft to support Stack Overflow Documentation for Microsoft developers - MSPoweruser
    Microsoft today announced partnership with Stack Overflow to support Stack Overflow Documentation for Microsoft developers. Stack Overflow Documentation is a new community-curated, example-focused developer documentation, based on the principles of Stack Overflow. via Pocket

codefest.at [MS]: Willkommen bei Microsoft AppSource

Die Art und Weise, wie wir heute Software und Services verwenden hat sich geändert. Heutzutage sind wir gewohnt, Apps rasch und einfach zu finden, zu installieren, anzusehen und zu verwenden. Um dieses Konzept auch im Business-Bereich umsetzen zu können, sind moderne Apps und eine entsprechende Infrastruktur erforderlich. Der neue AppSource Store macht dies möglich.

Der AppSource Store läuft ganz unter dem Motto “Find the right app for your business needs - Get solutions tailored to your industry that work with the products you already use”. Hier werden Lösungen für die Bereiche Microsoft Dynamics, Power BI, Office 365 und Azure gelistet.

Der AppSource Store steht unter https://appsource.microsoft.com bereit.

image

Der AppSource Store wird im Artikel Turning business process into business advantage for organizations everywhere unter blogs.microsoft.com vorgestellt.

AppSource kann nach Lösungen nach Kategorien, Branchen und Produkten gefiltert werden, wie etwa hier in diesem Beispiel.

image

 

Für Software-Entwickler ist diese Plattform interessant, um eigene Lösungen hier anzubieten.

image

Es sind nur wenige Felder auszufüllen, nämlich das Unternehmen, Kontaktinfos und eine kurze App-Beschreibung. Relevant ist natürlich auch die Art der App/Lösung:

image

Das wars auch schon. Nach dem Submit folgt eine kurze Info, dass sich Microsoft melden wird, um Details über die Lösung zu erfragen: “Thanks for telling us about your app! We’ll reach out to you with next steps soon”.

Wir sehen uns im AppSource Store…

Marco Scheel: Links for 2016-07-20 [del.icio.us]

Uli Armbruster: Should I stay or should I go: Wechselmotive analyisieren

In unserem Video, welches sich an Bewerber für die co-IT.eu GmbH richtet, sprechen wir das Thema Wechselgründe an. Die folgende Linksammlung soll euch bei eurer Entscheidung helfen.

 

 

Wir werden die Liste kontinuierlich erweitern, sofern wir gut Artikel finden. Der geneigte Leser kann gerne weitere Vorschläge einreichen oder von seinen Erfahrungen berichten.


Einsortiert unter:German, Links, Misc Tagged: Gehalt, Retrospektive, Stellenausschreibung

Sven Hubert: WiX Toolset Teil 5: Access denied! – Permissions setzen leicht gemacht

Herzlich willkommen zum fünften Teil der WiX-Blog-Serie. Jeder, der im Alltag mit Computern arbeitet, kommt irgendwann an einen Punkt, an dem Administratoren-Rechte auf dem System sehr hilfreich wären, um ein Problem schnell und unkompliziert zu lösen. Aus Sicht des IT-Supports wäre das gleichzusetzen mit absoluter Anarchie. Jeder macht was er will, keiner macht was er soll, aber alle machen mit. Beschränkungen stellen in der Regel sicher, dass nur diejenigen, die ganz genau wissen, was sie tun, tiefere Eingriffe in ein bestehendes System durchführen können. Dies gewährleistet einen konsistenten Zustand des Gesamt-Systems.

Trotzdem müssen auch Anwendern in bestimmten Bereichen weitreichende Rechte eingeräumt werden. Eine installierte Anwendung, die vom angemeldeten Nutzer zwar gesehen, aber nicht ausgeführt werden darf, kann auch nicht die Arbeitsleistung verbessern. Eine Anwendung, die eine Datei-basierte Datenbank benutzt, auf welcher der Anwender aber keine Schreib-Rechte hat, wird keine Daten persistieren können. Berechtigungen müssen also schon vor der ersten Ausführung einer Anwendung gesetzt werden. Am besten schon während der Installation. Dazu sind während der Installation zwar temporäre Administrations-Rechte nötig, diese werden bei vielen Firmen im Verteilungskonzept einer Software aber berücksichtigt. Wie sieht die Rechte-Vergabe mit Hilfe von WiX also aus?

Um das zu beantworten muss unterschieden werden zwischen drei zur Verfügung stehenden Elementen. Die Elemente Permission, PermissionEx und util:PermissionEx haben alle das gleiche Ziel: Berechtigungen setzen. Sie verfolgen jedoch verschiedene Wege um ans Ziel zu kommen.

Das Element PermissionEx ist ein mit WiX mitgeliefertes Element zum Schreiben von Berechtigungen. Es besitzt zwei Attribute: eine ID und einen SDDL-String (Security Descriptor Definition Language). Dieses Element ist nur für Installationsprojekte, die auf MSI 5.0 aufbauen verfügbar. Über den SDDL-String werden die genauen Berechtigungen des übergeordneten Elementes bestimmt. Denn eines haben alle Permission Elemente geminsam: Sie müssen stets einem anderen Element zugeordnet werden. Dies kann ein CreateFolder, ein File oder ein RegistryKey/Value Element sein. Somit werden die Berechtigungen auf einem Element gesetzt, das einem Component, und damit einem DirectoryRef-Element zugeordnet ist. Die Arbeit mit SDDL-Strings ist jedoch etwas gewöhnungsbedürftig und benötigt Einarbeitung, daher ist das PermissionEx-Element nicht für den Einstieg geeignet und soll hier nicht weiter betrachtet werden. Mehr Informationen über die Handhabung der SDDL-Strings findet man bei MSDN oder in verschiedenen Tutorials.

Das ebenfalls im Standard-WiX-Paket enthaltene Permission-Element kann mehrere Attribute beinhalten. Hier werden einzelne Berechtigungen über einzelne Attribute erteilt oder verweigert. Anders als das PermissionEx-Element, muss auch der User und die Domain des Users über ein Attribut definiert werden. Hierbei wird deutlich, dass ein Element auch mehrere Permission, beziehungsweise PermissionEx Elemente beinhalten kann, um unterschiedlichen Benutzern verschiedene Rechte-Sets zuzuweisen. Hierbei ist jedoch zu beachten, dass durch das Permission-Element, alle ACLs (Access Control List) überschrieben werden und somit nur noch die definierten Rechte-Sets gelten. Dies birgt bei unbedachtem Einsatz die Gefahr, sich selbst auszusperren. Im folgenden Beispiel gelten nach der Installation ausschließlich die definierten Rechte-Sets:

18-07-2016 15-54-24

Das letzte Element, das util:PermissionEx Element, ist kein Bestandteil des eigentlichen WiX-Pakets. Es ist in der Util-Extension enthalten und kann durch xmlns:util=“http://schemas.microsoft.com/wix/UtilExtension“ in den Installer eingebunden werden. Im Großen und Ganzen ähnelt das util:PermissionEx-Element dem mitgelieferten Permission-Element des WiX-Pakets. Der größte Unterschied ist jedoch, dass durch das util:PermissionEx-Element die ACLs nicht überschrieben, sondern modifiziert werden. Somit bleiben bestehende Berechtigungen, wie etwa der volle Zugriff für Administratoren, unberührt. Ein weiterer Vorteil des util:PermissionEx Elementes ist, dass ohne weiteres Zutun alle Unterordner die gleichen Berechtigungen wie der definierte Ordner erhalten.

Im Falle von Permission und util:PermissionEx werden Permissions einzeln als Attribut vergeben. Das Attribut Read setzt beispielsweise die Lese-Rechte des angegebenen Nutzers. Darüber hinaus existieren noch allgemeinere Rechte-Sammlungen. Neben GenericAll, was alle Rechte beinhaltet, gibt es noch GenericRead oder GenericWrite. Diese beinhalten verschiedene Rechte, die zum Lesen beziehungsweise Schreiben benötigt werden. Diese können nicht einzeln verboten werden, da sie implizit auch das Recht Synchronize beinhalten. Somit würde eine Anfrage für GenericRead fehlschlagen wenn GenericWrite verboten ist. Es wird daher empfohlen, explizit nur mit dem Erlauben von Rechten zu arbeiten, um solche impliziten Verkettungen auszuschließen.

Ein weiteres Pflicht-Attribut ist der User. Damit wird der Nutzer, für den die Berechtigung gesetzt werden soll, bestimmt. Dabei sind bestimmte Schlüsselwörter bereits vorhanden. Everyone, Administrators und Users werden auf jedem System erkannt. Darüber hinaus können weitere Benutzer beziehungsweise Gruppen angegeben werden. Dazu kann über das Domain-Attribut auch die entsprechende Domain  angegeben werden. Dies führt jedoch dazu, dass Installer an ein bestimmtes System angepasst werden müssen. Für interne Software einer Firma ist dies irrelevant, da nur das eigene System unterstützt werden muss. Falls das Zielsystem aber unbekannt ist, sollten nur die obigen allgemein erkannten Schlüsselwörter genutzt werden. Wesentlich einfacher kann dabei die Verwendung von Properties sein, die in Custom Actions mit den entsprechenden Werten gefüllt werden. Im folgenden Beispiel bleiben die bestehenden Rechte des Systems erhalten und werden entsprechend angepasst:

18-07-2016 15-50-29

Ausblick

Zu guter Letzt besteht natürlich immer die Möglichkeit, spezielle Wünsche über Custom Actions umzusetzen. Mit den Custom Actions sind dem Entwickler kaum noch Grenzen gesetzt, welche Vorgänge und Anpassungen während einer Installation durchgeführt werden sollen. Wie das aussieht, wird im nächsten Teil der WiX-Blog-Serie beleuchtet.

Uli Armbruster: Tools for Developers Session vom NET Open Space 2016

Zur Session „Tools & Practices for Developers“ habe ich mir Notizen gemacht. Wie versprochen findet ihr hier aufgelistet die genannten Tools. Ich habe nicht alle aufgeschrieben, also postet gerne weitere, wenn euch eines fehlt.

Mein Antrieb hinter der Session war der, dass ich meine tägliche Arbeit versuche so weit es geht zu optimieren und automatisieren. Wenn ich pro Tag 10 Minuten einsparen kann,was z.B. alleine durch TotalCommander möglich ist, so ergibt sich pro Jahr eine freigewordene Zeit von 43,5h.

 

Keepass Plugins

meine Keepass Plugins

Wenn ihr noch wichtige Tools aus eurer täglichen Arbeit nicht aufgelistet findet, dann schreibt mir und ich füge sie hinzu.

 

 

 


Einsortiert unter:German, Links, Misc Tagged: Community, Open Space

Marco Scheel: Links for 2016-07-17 [del.icio.us]

codefest.at [MS]: Microsoft Cognitive Services Emotion API Teil 4

Neben der Face-API habe ich kürzlich die Emotion API der Microsoft Cognitive Services ausprobiert. Beide Services basieren auf Machine Learning und interpretieren Gesichter aus Fotos (bzw. auch aus Videos). Während die Face API Basisinformationen über ein Gesicht liefern, versucht die Emotion API den Gesichtsausdruck von erkannten Gesichtern in Zahlen zu fassen. Die Emotion API beurteilt einen Ausdruck in verschiedenen Kategorien und liefert Wahrscheinlichkeiten retour. Das Ganze sieht dann so aus…

Der Startpunkt für die Emotion API ist https://www.microsoft.com/cognitive-services/en-us/emotion-api und die Documentation.

Auch hierfür gibt es ein Tutorial Get Started with Emotion API in C#, auf GitHub steht das Microsoft/Cognitive-Emotion-Windows Projekt zum Download bereit. Die Repo enthält die Windows Client Library und ein Beispiel mit einer Windows-App.

Build…

Allerdings ist für Windows SDK for the Microsoft Emotion API etwas Handarbeit nötig, um das Projekt zum Laufen zu bekommen. Das Projekt SampleUserControlLibrary muss extra geladen und in die Solution eingebunden werden. Dann lädt man noch in der NuGet Console das Paket Install-Package Microsoft.ProjectOxford.Emotion und fügt die Reference zum SampleUserControlLibrary in das EmotionAPI-WPF_Samples Project hinzu. Dann klappts auch mit dem Compile.

Ausprobieren

Nachdem diese technischen Voraussetzungen erfüllt sind, und die Solution ge-build-et werden kann, kann der Start der WPF App erfolgen. Das Demo startet mit der erforderlichen Key-Aufforderung.

image

Hier wird also zunächst der eigene “Emotion-Preview” Key benötigt. Diesen erhält man von https://www.microsoft.com/cognitive-services/en-us/subscriptions. Der kostenfrei Key kann für 30,000 transactions per month und 20-mal pro Minute verwendet werden. Diesen kopiert man und trägt in hier in das Subscription Key Feld ein und klickt auf Save Key. Damit wird der eigene Key auf die eigene Festplatte gespeichert und steht für die Zukunft in dieser App bereit.

Detect emotion using a stream

Beim Fortsetzen kann nun ein Bild oder ein Video ausgewählt werden. Ich habe diesmal ein Bild von mir verwendet, das nicht so neutral wie jenes von der Face API ist, sondern wo ich mir ein Lächeln abgerungen habe. Hinweis: In den Nutzungsbedingungen steht auch klar, dass Personen im Bild damit einverstanden sein müssen, dass das Bild hier verwendet wird… Gut, ich bin einverstanden.

Das Ergebnis sieht hier, mit der Emotion API, wie folgt aus:

image

Die Ergebnisse im Detail:

[17:17:44.959642]: EmotionServiceClient is created
[17:17:44.985143]: Calling EmotionServiceClient.RecognizeAsync()...
[17:17:46.279940]: Detection Result:
[17:17:46.282933]: Emotion[0]
[17:17:46.285444]:   .FaceRectangle = left: 122, top: 49, width: 53, height: 53
[17:17:46.287934]:   Anger    : 0.0003246186
[17:17:46.289450]:   Contempt : 0.002541366
[17:17:46.290972]:   Disgust  : 0.003764645
[17:17:46.297973]:   Fear     : 8.104636E-07
[17:17:46.299971]:   Happiness: 0.7857869
[17:17:46.302971]:   Neutral  : 0.2070151
[17:17:46.304972]:   Sadness  : 7.317301E-05
[17:17:46.307971]:   Surprise  : 0.0004933038

Man sieht hier also die erkannte Wahrscheinlichkeiten in verschiedenen Kategorien (Anger, Contempt, Disgust, Fear, Happiness, Neutral, Sadness, Surprise). Die Kategorien mit der höchsten Wahrscheinlichkeit werden neben dem Foto zusammengefasst. In meinem Beispiel sind das Happiness mit 78%, gefolgt von Neutral mit 20% und Disgust mit 0,3%. Witzig, 0,3% “Abscheu” hätte ich nicht interpretiert, allerdings ist das in diesem Beispiel auch völlig vernachlässigbar. Alle anderen Faktoren (wie Geringschätzung, Angst, Traurigkeit) werden von der Emotion API mit einer noch geringeren Wahrscheinlichkeit bewertet.

Technisch gesehen erfolgt das Ermitteln der Emotionen wie folgt.

image

…hier folgt dann die UploadAndDetectEmotions Methode mit dem Client (SDK) in DetectEmotionUsingStreamPage.xaml.cs. Diese erzeugt den Client mit dem Subscription Key und lädt das Bild in das Service.

image

…und die Ausgabe dieses Szenarios aus dem Beispiel durch Durchlaufen der emotionResult-Collection.

image

Weitere Szenarien funktionieren nach demselben Prinzip.

Detect emotion using a URL

Die zweite Option “Detect emotion using a URL” macht dasselbe, nur dass eben ein Bild-URL verwendet werden kann.

image

Wenn das Bild nicht entspricht (wie in meinem Fall), zeigt die API mögliche Ursachen an:

No emotion is detected. This might be due to:

  • image is too small to detect faces
  • no faces are in the images
  • faces poses make it difficult to detect emotions
  • or other factors

Mein Versuchsbild von der URL ist nur 150 Pixel breit und viel zu pixelig, um für brauchbare Ergebnisse verwendet zu werden. Verständlich, wenn sich die API dann beschwert.

Detect emotion using a video

Hierbei muss das Videofile als .mp4, .mov oder .wmv File auf der Festplatte vorliegen. Dieses wird nach der Auswahl zur Analyse an die Emotion API upgeloadet. Das Ergebnis wird in EmotionDetectionUsingVideoPage.xaml.cs von der async-Methode emotionServiceClient.GetOperationResultAsync(videoOperation) geliefert.

image

Ein Video wird in verschiedene Sequenzen zerlegt und analysiert. Das dauert natürlich je nach Video einige Zeit… mein Beispielvideo war zwar nur etwa 14 Sekunden lang, der Upload und die Analyse dauerte rund 3 Minuten.

image

Das Ergebnis der Videoanalyse zeigt die “Top 3 Emotions”. In diesem Video habe ich viele unterschiedliche Gesichtsausdrücke ausprobiert, von happy, über erstaunt bis neutral. Mein Ergebnis sah dann so aus:

image

Die Top 3 Kategorien meines Kurzvideos waren Neutral (51%), Erfreut (46%) und Verärgert (0,5%).
Mein Ausdruck für “überrascht” scheint wohl in Happiness aufgegangen zu sein. Winking smile

Hier der JSON-Output des ersten Gesichtsausdrucks (offensichtlich der Ausdruck “Happy”, visualisiert mit jsonvisualizer.com):

SNAGHTML11bc727

Aus dem Array werden dann die Top 3 Ausdrücke ausgegeben. So kann dann durch die Ergebnisse gelaufen werden und diese weiterverwendet werden.

Fazit

Die Emotion API stellt neben der Face API ein weiteres, cooles Cloud Service aus den Microsoft Cognitive Services dar. Bei Bildern funktionierte die Erkennung in meinem Beispielen ziemlich gut. Bei Videos ist das schwerer zu beurteilen und nachzuvollziehen. Auf jeden Fall sind beide Services für mich sehr beeindruckend. In zukünftiger Software (auch abseits von Spaß-Apps) wird es bestimmt Anwendungsfälle geben - mir fallen hier neben Überwachungsaspekten vor allem Beispiele in Bezug auf Menschen mit Behinderungen ein -, wo der Einsatz und die Bewertung der Gesichtserkennung Sinn macht.

Somit meine Empfehlung: Eine coole Sache. Am besten einmal die Beispiele selbst ausprobieren und damit experimentieren!

 

Quicklinks zu den vorigen Teilen dieser Serie über Cognitive Services:

codefest.at [MS]: Microsoft Cognitive Services Teil 3

In den ersten beiden Teilen über die Microsoft Cognitive Services ging es um die Face-API.Die Cognitive Services sind jedoch sehr umfangreich und bieten eine ganze Reihe von interessanten Beispielen, welche die Verwendung demonstrieren.

Viele Beispiele für die Microsoft Cognitive Services sind auf der SDKs & Samples SDKs & Samples Website aufgelistet.

image

Viele Samples liegen auf GitHub oder können direkt von dort bezogen werden. Bitte nicht vergessen, dass für die einzelnen Services ein eigener API-Key erforderlich ist, der von https://www.microsoft.com/cognitive-services/en-us/subscriptions bezogen und verwaltet werden kann. Die Liste kann nach Plattform und API gefiltert werden.

Ein Service, das wahrscheinlich oft in eigenen Apps/Webapps genutzt werden kann, ist das Microsoft Bot Framework: “Your bots — wherever your users are talking.”. In diesem Sinne ist ein “Bot” etwas Gutes. Er soll Benutzern Hilfestellung durch natürliche Fragen und Antworten geben. Der Startpunkt für Bots ist https://dev.botframework.com/.

image

Zum Entwickeln eigener Bots steht das Bot Framework Developer Portal bereit. Hier können eigene Bots registriert und konfiguriert werden, gewünschte Channels gewählt werden und der Bot im Bot Directory veröffentlicht werden. Alle so registrierten Bots sind auto-configured umd mit Skype und dem Web zu funktionieren.

Hinweis: Das Microsoft Bot Framework wurde bei der BUILD Conference vorgestellt. Mittlerweile, rund 3 Monate später, gibt es hier bereits Neuerungen und es liegt bereits die API V3 vor: Upgrade your bot to V3.

Viel Spaß beim Ausprobieren der Services!

Martin Richter: Samsung S4 (I9500 und I9295) mit Android 5.01 stürzen ab, wenn man die Google Kontoeinstellungen bearbeiten will

Vor über 2 Monaten fing es an. Nach irgend einem Update konnte ich auf einmal die Kontoeinstellungen meines Google Accounts auf meinem Samsung S4 Active mit Android 5.01 nicht mehr erreichen. Einstellungen -> Konten -> Google und Crash, Anwendung wird angehalten.

Relativ schnell fand ich Leidensgenossen im Netz, denen es genauso geht. Der häufigste Kommentar der Experten war: „Warten auf ein neues Google-Play-Store Update“. Andere setzten tatsächlich ihr Handy zurück und machten die wildesten Klimmzüge. Resultat war: Nach dem nächsten Update lief es wieder nicht.

Bis dato war es mir erstmal egal, aber jetzt wollte ich doch eine Einstellung ändern. Also noch mal gegoogelt und gleich in mehreren Threads einen simplen Workaround gefunden, wie man doch an sein Konto kommt und den Tipp möchte ich Euch auch gerne zukommen lassen:

  • Einfach Gallerie App öffnen
  • Einstellungen auswählen
  • Und da findet man auch das verwendete Google Konto.

Hier stürzt nichts ab und man kann die entsprechenden Einstellungen vornehmen.

Siehe unter anderem hier und auch hier.


Copyright © 2010 Martin Richter
Dieser Feed ist nur für den persönlichen, nicht gewerblichen Gebrauch bestimmt. Eine Verwendung dieses Feeds bzw. der hier veröffentlichten Beiträge auf anderen Webseiten bedarf der ausdrücklichen Genehmigung des Autors.
(Digital Fingerprint: bdafe67664ea5aacaab71f8c0a581adf)

codefest.at [MS]: Microsoft Cognitive Services Face API Teil 2

In Teil 1 ging es um das Erstellen einer einfachen App, um Gesichter auf Fotos mit der Face-API zu erkennen. Nun geht es darum, mehr über die Gesichter zu erfahren…

Ich habe das Beispiel aus dem Tutorial Get Started with Face API in C# etwas erweitert. Hier sehen wir das bisherige Ergebnis mit einer Person (mir) und dem erkannten Gesichtsfeld auf dem Foto. Sehen wir uns an, was die Face-API noch alles kann und welche Daten sie uns für eigene Apps liefern kann…

image_thumb[10]

Dazu habe ich das Sample (Code siehe hier) mit den Infos von der Face-API - How to Detect Faces in Image erweitert und mit demselben Bild (und weiteren, s.u.) experimentiert.

Somit habe ich einfach das verwendete Bild erneut mit FaceAttributes an das Service gesendet:

faceServiceClient.DetectAsync(s, returnFaceLandmarks: true, returnFaceAttributes: requiredFaceAttributes)

Der Screenshot zeigt die möglichen Attribute (Age, Gender, Smile, FacialHair, HeadPose, Glasses).

image_thumb[18]

Das Ergebnis und die erkannten Merkmale sind beeindruckend… von Alter, Geschlecht, Brillenträger-Info bis zum Smile-Faktor mit einer Wahrscheinlichkeit (0 bis 1 = 100%). Cool, oder?

image_thumb[22]

Schöner wird das Ganze, wenn man die Ergebnisse serialisiert und so ausgeben lässt:

var json = JsonConvert.SerializeObject(face);

image

Beim Erforschen entdeckt man weitere interessante Details… etwa in FacialHair, ob ein Bart, Schnurrbart oder Kotletten erkannt wurden.

Geliefert werden auch die X und Y-Position der wichtigsten Gesichtsmerkmale im Bild (FaceLandmarks). Das kann hilfreich für das Erkennen von Gesichtsausdrücken und für die Steuerung der eigenen App sein.

image

Diese Eigenschaften sind hier visualisiert.

image

…sowie die Haltung des Kopfes. In meinem Beispiel ist Pitch 0 Grad, Roll –1.8 Grad und Yaw +1 Grad. Die Person im Bild oben hat den Kopf ganz leicht nach links geneigt.

image

Die folgende Grafik aus dem Glossar und Infos aus Face API - V1.0 helfen, die Werte zu verstehen.

image

Natürlich habe ich auch mit weiteren Beispielbildern experimentiert. Bei einem Bild eines (grinsenden = 93% Wahrscheinlichkeit) Brillenträges (ReadingGlasses) hat das auch brav funktioniert…

image

Ebenso hat mein Versuch mit einem Bild von Martina gut geklappt… Winking smile

image_thumb[43]

image

Natürlich musste ich auch ein (spätes) Foto von Elvis Presley ausprobieren… es wäre wegen den Kotletten. Viel mehr Sideburns geht bei dem Foto (das ich aus Copryright Gründen hier nicht poste) eigentlich nicht, aber – you get the idea - die Sideburns werden erkannt: 0.2 und Beard 0.3. Das Alter…hm auch Elvis war mal jung…

image

Zugegeben, ich bin von diesem Service recht beeindruckt. Wie in Teil 1 erwähnt, muss die Qualität der Bilder, die Auflösung, die Lichtverhältnisse und die Konstellation der Personen für eine korrekte Erkennung natürlich ausreichen. Bei meinen Versuchen erkannte die Face-API – bei guter Bildqualität - recht zuverlässig Daten aus den Fotos. Umgekehrt gab es auch Fotos, wo gar keine Gesichter erkannt wurden.

Die Face-API liegt derzeit (siehe Endpoint https://api.projectoxford.ai/face/v1.0/detect) als Version 1.0 vor. Offensichtlich wird für die Public-Demo http://how-old.net/ eine ältere Version verwendet, diese liefert teilweise unterschiedliche Ergebnisse. Zum Herumspielen ist die Website aber allemal gut. Aus meiner Sicht liefert das eigene V1 Demo jedoch bessere Ergebnisse. Wichtig ist auch der Gesichtsausdruck. Je neutraler (Stichwort Passfoto), desto genauer ist auch die Altersermittlung.

Manche Cognitive Services können in eigenen Applikationen durchaus Sinn machen. Die Verwendung (der Face-API) ist denkbar einfach. Alleine die Möglichkeit solche Funktionen einfach zu benutzen (und nicht selbst entwickeln oder zukaufen zu müssen), beflügeln Gedanken zur Integration in eigene Software-Lösungen.

Die Spielwiese ist eröffnet! Viel Spaß beim Erforschen der Microsoft Cognitive Services!

In Teil 3 gibts dann noch Hinweise für weitere Beispiele.

Kay Giza [MS]: Visual Studio Code 1.3 - Tabs, Extensions View und mehr Neuigkeiten

Visual Studio Code (VSCode) hat mir Version 1.3 einige entscheidende Verbesserungen und Highlights erhalten. In diesem Blogeintrag möchte ich einige der Neuigkeiten vorstellen. Eine... [... mehr in diesem Blogeintrag auf Giza-Blog.de]


This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
© Copyright 2006-2016 Kay Giza. All rights reserved. Legal

codefest.at [MS]: Microsoft Cognitive Services Face API Teil 1

Die Art und Weise, wie wir in Zukunft Computer bedienen werden, wird sich ändern. Neben den gewohnten Mechanismen mit Tastatur, Maus, Touch und Spracheingabe wird Software zunehmend intelligenter und besser auf den User eingehen und die Kommunikation mit der Maschine vereinfachen.

Zu diesem Zweck forschen Software-Entwickler daran, Machine Learning zu verbessern und Services bereitzustellen, welche APIs zur Konsumentation von Logik in eigene Apps erlauben.

Microsoft hat kürzlich die Cognitive Services vorgestellt, die mehr als zwanzig (!) verschiedene Cloud-Services zur Integration in eigene Apps anbieten. Der Projektname lautete übrigens “Project Oxford”. Die Cognitive Services sind derzeit noch in Preview und die Endpoints und Libraries heißen auch noch “Project Oxford”.

Die Website https://www.microsoft.com/cognitive-services zeigt alle verfügbaren Services.

image

Ich habe mir ein einfaches Service herausgepickt, um dieses selbst einmal auszuprobieren, nämlich die Face-API aus der Vision-Kategorie.

image

Der Startpunkt ist Face-API Webseite.
Die Face-API Dokumentation liefert den Überblick und weitere Links zu Beispielen.

Das Tutorial Get Started with Face API in C# zeigt die ersten Schritte zum Ausprobieren. Los gehts!

Als Voraussetzung ist für jedes Service ein (derzeit kostenfreier) API Key erforderlich. Dieser kann unter https://www.microsoft.com/cognitive-services/en-us/sign-up mit einem Microsoft Account (MSA) angefordert werden.

Die Verwaltung der Keys erfolgt unter https://www.microsoft.com/cognitive-services/en-us/subscriptions.

image

In meinem Fall benötige ich das “Face-Preview” Service. Hier muss der Key für die Face-API angezeigt werden (ein Key ist ausreichend) und hier können die Keys verwaltet werden.

Noch ein Wort zu den Preisen: Diese richten sich nach dem Service und der Nutzung. Soweit ich gesehen habe, sind alle Services bis zu einem Volumen von 5,000 transactions per month kostenfrei! Die aktuellen Preise sind unter Preview pricing ersichtlich.

image

Damit können wir das Demoprojekt starten. Zunächst wird in Schritt 1 mit Visual Studio ein neues WPF Projekt angelegt und in Schritt 2 mit dem NuGet Package Manager das Paket Newtonsoft.Json installiert.

Die Cognitive Services sind per HTTPS Request gegen den entsprechenden Cloud-Endpoint aufrufbar. Dieser lautet (siehe Face API - V1.0):

https://api.projectoxford.ai/face/v1.0/detect[?returnFaceId][&returnFaceLandmarks][&returnFaceAttributes]

Für die .NET Plattform gibt es zur einfacheren Nutzung Client Libraries, um die Web-Requests einzukapseln und um das Service bequemer zu verwenden. In Schritt 3 wird nun die Client-Library “Microsoft.Project Oxford.Face” über NuGet wie folgt bezogen.

image

Danach werden die Libraries zu MainWindow.xaml.cs hinzugefügt:

using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Face.Contract;

…und ein Interface mit dem eigenen Subscription Key (aus der eigenen Subscription von oben) in der MainWindow class erstellt:

private readonly IFaceServiceClient faceServiceClient = new FaceServiceClient("Your subscription key");

Das wars schon mit den ersten Vorbereitungen für das App-Framework. Nun geht es um den eigentlichen Code zur Verwendung der Face-API.

Wir verwenden die Face-Detect API um ein Bild direkt upzuloaden. Der Link führt direkt zur Dokumentation des Endpoints. Für asynchrone Methoden kann die DetectAsync methode des FaceServiceClient verwendet werden. Jedes retournierte Gesicht enthält ein Rechteck um die Position im Foto zu markieren, das mit Face Attributes ergänzt ist. In Schritt 4 wird der FaceServiceClient verwendet.

In Schritt 5 des Tutorials wird die ButtonClick Methode async und das Ergebnis ausgewertet. Dabei wird pro erkanntem Gesicht ein rotes Rechteck über die Position gezeichnet. Dazu habe ich ein Schwarz/Weiß-Foto von mir verwendet, das Beispiel zeigt den Output.

image

Sehr schön. Das Beispiel klappt und markiert das erkannte Gesicht auf dem Foto. In meinem Beispiel besteht das Array faceRects aus nur einem Face.

Die Qualität der Bilder muss natürlich ausreichend sein. Auch Gruppenfotos (hier ein Schnappschuss der Audience vom letzten Microsoft Community Open Day in München) liefern beeindruckende Ergebnisse.

image

In Teil 2 interessieren mich jedoch noch weitere Details und was die Face-API so alles erkennen und liefern kann…

Manfred Steyer: Slides and Sample from my talk about the newest new Router in Angular 2 at @angular_berlin in July 2017

Please find below the slides and the sample from my talk about the newest new Router in Angular 2 that I did at @angular_berlin in July 2017.

The samples show:

  • How to configure the router
  • How to create hierarchical routes
  • How to use Aux-Routes
  • How to use Guards, e. g. for Authentication 
  • How to use modern Auth with OAuth2 und OIDC using my npm-package angular2-ouath2

The slides give an outlook to the upcomming lazy-loading features.


Downloads

Christian Giesswein: Developer Week 2016 - Ein Rückblick

Schön war sie, die #dwx16.. und auch schon ein paar Wochen her.
Leider kam ich noch nicht dazu ein paar Worte über diese Konferenz zu verlieren.

Die Developer Week 2016 fand wieder in Nürnberg im Konferenzzentrum statt und ist im .NET Umfeld, im deutschsprachigen Bereich eine der größten Konferenzen mit fast 2000 Teilnehmern. Als Entwickler hat man auf dieser Konferenz glaub ich die Qual der Wahl welchen Vortrag man denn nun besuchen möchte.
Für mich war es als Sprecher eine recht stressige aber sehr schöne Zeit, schließlich war ich mit 4,5 Vorträgen auf der Konferenz vertreten.

Am Montag gleich das erste, spannende Thema "Datenbindung Deluxe – Deep Dive in das Binding von WPF" wo der Saal platzend voll war, sogar vor der Bühne noch Leute im Schneidersitz saßen - als Sprecher immer ein gutes Gefühl und auch die Gespräche im Anschluss zeigten ein hohes Interesse an dem Thema.

Weiter ging es am Montagnachmittag gleich mit "Modulares UI - MVVM mit Prism 6" wo in rasanten 60 Minuten die Grundprinzipien von PRISM erläutert wurde und eine Kleine Basisanwendung mit PRISM entwickelt wurde. Wie üblich bei all meinen Vorträgen, zu 99% mit Visual Studio statt mit Powerpoint - Praxis pur!

Am Dienstag begann der Tag dann etwas ruhiger, da war am Nachmittag dann eine zweistündige "DevSession" zum Thema "Entity Framework und WPF" statt, wo es um die Best Practices im Umgang von Entity Framework MIT WPF ging. Also Erfahrungen womit zwei Technologien zusammengefasst wurden.

Der letzte Tag, am Mittwoch, fing dann bereits in der Früh mit "Visual Studio 2015 Extensions leichtgemacht" an, wo es um das Entwickeln von eigenen Erweiterungen für Visual Studio 2015 ging. Obwohl das Thema sicherlich nicht das gängigste ist, haben sich auch hier sehr viele Teilnehmer eingefunden um in der Früh sich mal über das Thema zu informieren. Dabei kam am Ende eine kleine Erweiterung raus, die "mal eben schnell" von mehreren Projekten in der Solution die .NET Version verändert.

Ging ich aus diesem Vortrag noch raus mit dem Gefühl *puh,.. das war’s* sprangen mein geschätzter Kollege David Tielke und ich für eine Ersatzsession am Nachmittag ein.
Dabei haben wir uns das Thema "Back to the Future - Eine Zeitreise - von C# 1.0 bis 7.0" eine knackige aber sehr unterhaltsame Session zum Thema C# überlegt.
Ich glaube nach dieser Session ist wohl jeder mit sehr guter Laune und einem Lächeln zur Abschlusskeynote von Scott Hanselman gegangen.

Persönlich bleibt mir die Developer Week 2016 in Nürnberg sehr gut in Erinnerung, viele Sprecher als auch Teilnehmer kennt man mittlerweile von den .NET Konferenzen die das ganze Jahr über so vergehen und man geht mit sehr viel neuen Input nach Hause.

Alle Codebeispiele sind auf GitHub veröffentlich und können dort heruntergeladen werden: https://github.com/softwaretirol/conferences
Ich freue mich auf jeden Fall auf eine Developer Week 2017 und hoffe, dass auch die Konferenz wieder so gelungen wird wie die vergangene.

 

Die Unterlagen:

Jürgen Gutsch: Working with user secrets in ASP.​NET Core applications.

In the past there was a study about critical data in GitHub projects. They wrote a crawler to find passwords, user names and other secret stuff in projects on GitHub. And they found a lot of such data in public projects, even in projects of huge companies, which should pretty much care about security.

the most of this credentials are stored in config files. For sure, you need to configure the access to a database somewhere, you also need to configure the credentials to storages, mail servers, ftp, what ever. In many cases this credentials are used for development, with lot more rights than the production credentials.

Fact is: Secret information shouldn't be pushed to any public source code repository. Even better: not pushed to any source code repository.

But what is the solution? How should we tell our app where to get this secret information?

On Azure, you are able to configure your settings directly in the application settings of your web app. This overrides the settings of your config file. It doesn't matter if it's a web.config or an appsettings.json.

But we can't do the same on the local development machine. There is no configuration like this. How and where do we save secret credentials?

With .Core, there is something similar now. There is a SecretManager tool, provided by the .NET Core SDK (Microsoft.Extensions.SecretManager.Tools), which you can access with the dotnet CLI.

This tool stores your secrets locally on your machine. This is not a high secure password manager like keypass. It is not really high secure, but on your development machine, it provides the possibility NOT to store your secrets in a config file inside your project. And this is the important thing here.

To use the SecretManager tool, you need to add that tool in the "Tools" section of your project.json, like this:

"Microsoft.Extensions.SecretManager.Tools": {
  "version": "1.0.0-preview2-final",
  "imports": "portable-net45+win8+dnxcore50"
},

Be sure you have a userSecretsId in your project.json. With this ID the SecretManager tool assigns the user secrets to your app:

"userSecretsId": "aspnet-UserSecretDemo-79c563d8-751d-48e5-a5b1-d0ec19e5d2b0",

If you create a new ASP.NET Core project with Visual Studio, the SecretManager tool is already added.

Now you just need to access your secrets inside your app. In a new Visual Studio project, this should also already done and look like this:

public Startup(IHostingEnvironment env)
{
    _hostingEnvironment = env;

    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see 
        // http://go.microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();

        // This will push telemetry data through Application 
        // Insights pipeline faster, allowing you to view results 
        // immediately.
        builder.AddApplicationInsightsSettings(developerMode: true);
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

If not arr a NuGet reference to Microsoft.Extensions.Configuration.UserSecrets 1.0.0 in your project.json and add builder.AddUserSecrets(); as shown here.

The Extension Method AddUserSecrets() loads the secret information of that project into the ConfigurationBuilder. If the keys of the secrets are equal to the keys in the previously defined appsettings.json, the app settings will be overwritten.

If this all is done you are able to use the tool to store new secrets:

dotnet user-secrets set key value

If you create a separate section in your appsettings.config as equal to the existing settings, you need to combine the user secret key with the sections name and the settings name, separated by a colon.

I created settings like this:

"AppSettings": {
    "MySecretKey": "Hallo from AppSettings",
    "MyTopSecretKey": "Hallo from AppSettings"
},

To overwrite the keys with the values from the SecretManager tool, I need to create entries like this:

dotnet user-secrets set AppSettings:MySecretKey "Hello from UserSecretStore"
dotnet user-secrets set AppSettings:MyTopSecretKey "Hello from UserSecretStore"

BTW: to override existing keys with new values, just call set the secret again with the same key and the new value.

This way to handle secret data works pretty fine for me.

The SecretManager tool knows three more commands:

  • dotnet user-secrets clear: removes all secrets from the store
  • dotnet user-secrets list: shows you all existing keys
  • dotnet user-secrets remove <key>: removes the specific key

Just type dotnet user-secrets --help to see more information about the existing commands.

If you need to handle some more secrets in your project, it possibly makes sense to create a small batch file to add the keys, or to share the settings with build and test environments. But never ever push this file to the source code repository ;)

Code-Inside Blog: CAKE: Building solutions with C# & Roslyn

x

CAKE - C# Make

  • A DSL for build tasks (e.g. build following projects, copy stuff, deploy stuff etc.)
  • It’s just C# code that gets compiled via Roslyn
  • Active community, OSS & written in C#
  • You can get CAKE via NuGet
  • Before we begin you might want to check out the actual website of CAKE
  • Cross Platform support

Our goal: Building, running tests, package NuGet Packages etc.

I already did a couple of MSBuild and FAKE related blogposts, so if you are interested on these topics as well go ahead (some are quite old, there is a high chance that some pieces might not apply anymore):

Ok… now back to CAKE.

Let’s start with the basics: Building

I created a pretty simple WPF app and followed these instructions.

The build.cake script

My script is a simplified version of this build script:

// ARGUMENTS
var target = Argument("target", "Default");

// TASKS
Task("Restore-NuGet-Packages")
    .Does(() =>
{
    NuGetRestore("CakeExampleWithWpf.sln");
});

Task("Build")
    .IsDependentOn("Restore-NuGet-Packages")
    .Does(() =>
{
      MSBuild("CakeExampleWithWpf.sln", settings =>
        settings.SetConfiguration("Release"));

});

// TASK TARGETS
Task("Default").IsDependentOn("Build");

// EXECUTION
RunTarget(target);

If you know FAKE or MSBuild, this is more or less the same structure. You define tasks, which may depend on other tasks. At the end you invoke one task and the dependency chain will do its work.

Invoke build.cake

The “build.ps1” will invoke “tools/cake.exe” with the input file “build.cake”.

“build.ps1” is just a helper. This Powershell script will download nuget.exe and download the CAKE NuGet-Package and extract it under a /tools folder. If you don’t have problems with binary files in your source control, you don’t need this Powershell script.

Our first CAKE script!

The output is very well formatted and should explain the mechanics behind it good enough:

Time Elapsed 00:00:02.86
Finished executing task: Build

========================================
Default
========================================
Executing task: Default
Finished executing task: Default

Task                          Duration
--------------------------------------------------
Restore-NuGet-Packages        00:00:00.5192250
Build                         00:00:03.1315658
Default                       00:00:00.0113019
--------------------------------------------------
Total:                        00:00:03.6620927

The first steps are pretty easy and it’s much easier than MSBuild and feels good if you know C#.

The super simple intro code can be found on GitHub.

Jürgen Gutsch: How web development changed for me over the last 20 years

The web changed pretty fast within the last 20 years. More and more logic moves from the server side to the client side. More complex JavaScript needs to be written on the client side. And something freaky things happened the last years: JavaScript was moving to the server and Web technology was moving to the desktop. That is nothing new, but who was thinking about that 20 years ago?

The web changed, but also my technology stack. It seems my stack changed back to the roots. 20 years ago, I started with HTML and JavaScript, moving forward to classic ASP using VBScript. In 2001 I started playing around with ASP.NET and VB.NET and used it in in production until the end of 2006. In 2007 I started writing ASP.NET using C#. HTML and JavaScript was still involved, but more or less wrapped in third party controls and jQuery was an alias for JavaScript that time. All about JavaScript was just jQuery. ASP.NET WebForms felled pretty huge and not really flexible, but it worked. Later - in 2010 - I also did many stuff with SilverLight, WinForms, WPF.

ASP.NET MVC came up and the web stuff starts to feel little more naturally again, than ASP.NET WebForms. From an ASP.NET developer perspective, the web changed back to get better, more clean, more flexible, more lightweight and even more naturally.

But there was something new coming up. Things from outside the ASP.NET world. Strong JavaScript libraries, like KnockOut, Backbone and later on Angular and React. The First Single Page Application frameworks (sorry, I don't wanted to mention the crappy ASP.NET Ajax thing...) came up, and the UI logic moves from the server to the client. (Well, we did a pretty cool SPA back in 2005, but we didn't thought about to create a framework out of it.)

NodeJS change the world again, by using JavaScript on the server. You just need two different languages (HTML and JavaScript) to create cool web applications. I didn't really care about NodeJS, except using it in the back, because some tools are based on it. Maybe that was a mistake, who knows... ;)

Now we got ASP.NET Core, which feels a lot more naturally than the classic ASP.NET MVC.

Naturally in this case means, it feels almost the same as writing classic ASP. It means using the stateless web and working with the stateless web, instead of trying to fix it. Working with the Request and Response more directly, than with the classic ASP.NET MVC and even more than in ASP.NET WebForms. It doesn't mean to write the same unstructured, crappy shit than with classic ASP. ;)

Since we got the pretty cool client side JavaScript frameworks and simplified, minimalistic server side frameworks, the server part was reduced to just serve static files and to serve data over RESTish services.

This is the time where it makes sense to have a deeper look into TypeScript. Until now it didn't makes sense to me. I was writing JavaScript for around 20 years, more and less complex scripts, but I never wrote so much JavaScript within a single project, than as I started using AngularJS last years. Angular2 also was the reason to have a deep look into TypeScript, 'cause now it is completely written in Typescript. And it makes absolutely sense to use it.

A few weeks ago I started the first real NodeJS project. A desktop application which uses NodeJS to provide a high flexible scripting run-time for the users. NodeJS provides the functionality and the UI to the users. All written in TypeScript, instead of plain JavaScript. Why? Because TypeScript has a lot of unexpected benefits:

  • You are still able to write JavaScript ;)
  • It helps you to write small modules and structured code
  • it helps you to write NodeJS compatible modules
  • In general you don't need to write all the JavaScript overhead code for every module
  • You will just focus on the features you need to write

This is why TypeScript got a great benefit to me. Sure a typed language is also useful in many cases, but - working with JS for 20 years - I also like the flexibility of the implicit typed JavaScript and I'm pretty familiar with it. that means, from my perspective the Good thing about TypeScript is, I am still able to write implicit typed code in TypeScript and to use the flexibility of JavaScript. This is why I wrote "You are still able to write JavaScript"

The web technology changed, my technology stack changed and the tooling changed. All the stuff goes more lightweight, even the tools. The console comes back and the IDEs changed back to the roots: Just being text editors with some benefits like syntax highlighting and IntelliSense. Currently I prefer to use the "Swiss army knife" Visual Studio Code or Adobe Brackets, depending on the type of project. Both are starting pretty fast and include nice features.

Using that light weight IDEs is pure fun. Everything is fast, because the machines resource could be used by the apps I need to develop, instead by the IDE I need to use to develop the apps. This makes development a lot faster.

Starting the IDE today means, starting cmder (my favorite console on windows). changing to the project folder, starting a console command to watch the typescript files, to compile after save. Starting another console to use the tools like NPM, gulp, typings, dotnet CLI, NodeJS, and so on. Starting my favorite light weight editor to write some code. :)

Jürgen Gutsch: Writing blog posts using Pretzel

Until yet I wrote more than 30 blog posts with Pretzel and it works pretty well. From my current perspective it was a good decision, to do this huge change, to move to that pretty cool and lightweight system.

I'm using MarkdownPad 2 to write the posts. Writing goes much easier. The process is now simplified and publishing is almost automated. I also added my blog CSS to that editor to have a nice preview.

The process of writing and publishing new posts goes like this:

  1. Creating a new draft article and save it in the _drafts folder
  2. Working on that draft
  3. Move the finished article to the _posts folder
  4. Commit and push that post to GitHub
  5. Around 30 seconds later the post is published on Azure

This process allows me to write offline in the train, while traveling to the Office in Basel. This is the most important thing to me.

The other big change, was switching to English. I now get more readers and feedback from around the world. Now the most readers are from the US, UK, India and Russia. But also from the other European countries, Australia, Middle East (and Cluj in Romania).

Maybe I lost some readers from the German speaking Area (Germany, Switzerland and Austria) who liked to read my posts in German (I need to find a good translation service to integrate) and I got some more from around the world.

Writing feels good in both, English and in the MarkdownPad :) From my perspective it was a good decision to change the blog system and even the language.

to learn more about Pretzel, have look into my previous post about using pretzel.

Sven Hubert: WiX Toolset Teil 4: Manuell starten war gestern – Autostart und Conditions

In diesem Teil der WiX-Blog-Serie steht das Thema Autostart im Fokus. Die zwei größten Anwendungsfälle für diese Funktion sind das Starten eines benötigten Services im Hintergrund, sowie eine Komfortfunktion um Programme, die man während der Arbeit benötigt, nicht mehr manuell starten zu müssen. Dazu wird im Laufe einer Installation oft gefragt, ob das installierte Programm beim Systemstart direkt mit ausgeführt werden soll. Wie diese Funktion über einen WiX Installer umgesetzt werden kann, soll im Folgenden beschrieben werden.

Um die Auswahl zu ermöglichen, wird zwischen dem aus Teil zwei der WiX Toolset Blogserie bekannten EULA-Dialog und dem Verifizierungs-Dialog ein weiterer Installationsschritt eingebaut, in dem ausgewählt werden kann, ob bestimmte Funktionen aktiviert werden sollen. In diesem Fall betrifft es das Erstellen des Desktop-Icons sowie das Ausführen der Anwendung beim Systemstart. Der Dialog enthält außer zwei Checkboxen und den bekannten Buttons Back, Next und Cancel keine weitere Logik:

clip_image002[4]

clip_image004[4]

 

Besonders wichtig sind die beiden Controls AutomaticStartup und DesktopCreation. Sie referenzieren jeweils ein Property, welches zusätzlich angelegt werden muss. Um die Übersicht zu behalten, wird empfohlen alle anfallenden Properties in ein eigenes Fragment auszulagern. Im Beispiel wird das Property in dem Fragment angelegt, in dem es von einer Komponente benutzt wird. Innerhalb des DesktopShortcut-Component-Elements wird daraufhin ein zusätzliches Element Condition gelegt, das den Wert der entsprechenden Property überprüft. Das Ergebnis wird im folgenden Screenshot dargestellt:

clip_image006[4]

Dass eine Anwendung beim Systemstart ausgeführt wird, lässt sich auf zwei Arten erreichen: Man kann eine Verknüpfung im StartupFolder von Windows anlegen, oder einen Eintrag in der Registry vornehmen. Der einfachste Weg ist dabei das Hinzufügen einer Verknüpfung in den StartupFolder. Dazu wird der Directory-Struktur der Knoten StartupFolder hinzugefügt, unter dem anschließend ein weiterer Shortcut angelegt wird. Diese Variante bietet zum einen den Charme, sehr simpel zu sein. Des Weiteren kann der Nutzer jederzeit selbstständig ohne größere Komplikationen die Verknüpfung aus dem StartupFolder löschen und somit das Ausführen beim Systemstart verhindern. Ein weiterer Punkt ist die Tatsache, dass der Verknüpfung im StartupFolder Parameter übergeben werden können, die den Programmstart beeinflussen.

clip_image008[4]

Eine weitere Variante, um die Anwendung beim Systemstart auszuführen, ist ein Eintrag in der Registry unter Software \Microsoft\Windows\CurrentVersion\Run. Besonderes Augenmerk sollte darauf auf das Root-Attribut des RegistryValue-Elementes gelegt werden. Dieses Attribut gibt an, ob die Anwendung für die Maschine, also unabhängig vom Nutzer, oder ob sie erst nach der Anmeldung eines bestimmten Nutzers gestartet werden soll. Der Registry-Eintrag zeigt dabei auf die ausführbare Datei im Installationsverzeichnis. Da sich ein Condition-Element stets auf das gesamte Component-Element bezieht, werden für das Setzen des Autostarts über die Registry zwei Component-Elemente benötigt. Dabei enthält die erste Komponente die ausführbare Datei und die zweite das RegistryValue, sowie das Condition-Element zur Überprüfung, ob der Nutzer einen Autostart möchte. Die zweite Komponente wird somit nur installiert, wenn die Condition zutrifft.

clip_image010[4]

Stefan Henneken: IEC 61131-3: Arrays mit variabler Länge

Bei der Deklaration von Arrays musste bisher immer eine konstante Größe angegeben werden. Ab der 3rd Edition der IEC 61131-3 können Arrays mit einer variablen Länge deklariert werden. Funktionen lassen sich dadurch deutlich generischer anlegen als bisher.

Zwar können für die Arraygrenzen auch Variablen benutzt werden, diese Variablen müssen aber als Konstanten deklariert werden. Eine Anpassung der Arraygrenzen zur Laufzeit ist somit nicht möglich.

PROGRAM MAIN
VAR
  arrData             : ARRAY[1..ARRAY_UPPER_BOUND] OF INT;
END_VAR
VAR CONSTANT
  ARRAY_UPPER_BOUND   : INT := 10;	
END_VAR

Gerade wenn Arrays als Parameter an Funktionen oder Funktionsblöcken übergeben werden, stellen feste Arraygrenzen eine unangenehme Limitierung dar. Ist diese nicht hinnehmbar, musste bisher auf Pointerarithmetik gewechselt werden, mit allem Nachteilen. Hier ein einfaches Beispiel, welches die Summe eines eindimensionalen Arrays von LREAL-Variablen berechnet.

FUNCTION F_CalcSum1DimArrayOldSchool : LREAL
VAR_INPUT
  pData           : POINTER TO LREAL;
  nSize           : UDINT;
END_VAR
VAR
  pDataIndex      : POINTER TO LREAL;
  nUpperIndex     : UDINT;
  nIndex          : UDINT;
END_VAR

F_CalcSum1DimArrayOldSchool := 0;
nUpperIndex := nSize / SIZEOF(pDataIndex^);
IF (nUpperIndex > 0) THEN
  FOR nIndex := 0 TO (nUpperIndex - 1) DO
    pDataIndex := pData + (nIndex * SIZEOF(pDataIndex^));
    F_CalcSum1DimArrayOldSchool := F_CalcSum1DimArrayOldSchool + pDataIndex^;	
  END_FOR
END_IF

Die Funktion kann für die Addition beliebiger LREAL-Arrays genutzt werden. Sie ist unabhängig von der Anzahl der Elemente und von der oberen und unteren Arraygrenze.

PROGRAM MAIN
VAR
  array01    : ARRAY[2..8] OF LREAL := [16.1, 34.1, 4.1, 43.1, 35.1, 2.1, 65.1];
  lrSum01    : LREAL;
	
  array02    : ARRAY[-1..2] OF LREAL := [16.1, 34.1, 9.1, 13.1];
  lrSum02    : LREAL;
	
  array03    : ARRAY[-3..-1] OF LREAL := [16.1, 34.1, 8.1];
  lrSum03    : LREAL;
END_VAR
lrSum01 := F_CalcSum1DimArrayOldSchool(ADR(array01), SIZEOF(array01));
lrSum02 := F_CalcSum1DimArrayOldSchool(ADR(array02), SIZEOF(array02));
lrSum03 := F_CalcSum1DimArrayOldSchool(ADR(array03), SIZEOF(array03));

Beispiel 1 (TwinCAT 3.1.4020)

Allerdings hat diese Lösung einige Nachteile. Zum einen eben die Tatsache das Pointerarithmetik benutzt werden muss. Der Quellcode der Funktion wird schon bei relativ einfachen Aufgaben recht komplex. Zum anderen muss an die Funktion auch eine Größen- bzw. Längenangabe übergeben werden. Bei dem Aufruf muss also sichergestellt werden, das der Pointer auf das Array und die Längenangabe übereinstimmen.

Seit der 3rd Edition der IEC 61131-3 können Arrays auch mit variabler Arraygrenze definiert werden. Statt der Arraygrenze, wird ein ’*’ angegeben:

arrData   : ARRAY[*] OF LREAL;

Wird die Funktion aufgerufen, so muss das übergebene Array konstante Arraygrenzen besitzen. In der Funktion kann über die Funktionen LOWER_BOUND und UPPER_BOUND die jeweilige obere- und untere Arraygrenze abgefragt werden.

Derzeit können Arrays mit variabler Länge nur an VAR_IN_OUT Variablen von Funktionen, Funktionsblöcken und Methoden übergeben werden (bleibt zu hoffen, dass in Zukunft auch VAR_INPUT und VAR_OUTPUT Variablen unterstützt werden).

Hier das angepasste Beispiele:

FUNCTION F_CalcSum1DimArray : LREAL
VAR_IN_OUT
  arrData    : ARRAY[*] OF LREAL;
END_VAR
VAR
  nIndex     : DINT;
END_VAR
F_CalcSum1DimArray := 0;
FOR nIndex := LOWER_BOUND(arrData, 1) TO UPPER_BOUND(arrData, 1) DO
  F_CalcSum1DimArray := F_CalcSum1DimArray + arrData[nIndex];
END_FOR

Die Funktion erwartet als Eingangsparameter nur noch ein Array von LREAL-Werten. Die Anzahl der Array-Elemente ist variabel. Mit LOWER_BOUND und UPPER_BOUND kann eine Iteration über das gesamte Array durchgeführt werden. Der Quellcode ist deutlich lesbarer als im ersten Beispiel.

PROGRAM MAIN
VAR
  array01    : ARRAY[2..8] OF LREAL := [16.1, 34.1, 4.1, 43.1, 35.1, 2.1, 65.1];
  lrSum01    : LREAL;
	
  array02    : ARRAY[-1..2] OF LREAL := [16.1, 34.1, 9.1, 13.1];
  lrSum02    : LREAL;
	
  array03    : ARRAY[-3..-1] OF LREAL := [16.1, 34.1, 8.1];
  lrSum03    : LREAL;
END_VAR
lrSum01 := F_CalcSum1DimArray(array01);
lrSum02 := F_CalcSum1DimArray(array02);
lrSum03 := F_CalcSum1DimArray(array03);

Beispiel 2 (TwinCAT 3.1.4020)

Auch werden mehrdimensionale Arrays unterstützt. Bei der Deklaration müssen alle Dimensionen als variabel angelegt werden:

arrData    : ARRAY[*, *, *] OF LREAL;

Der zweite Parameter von UPPER_BOUND und LOWER_BOUND gibt die Dimension an, von der die jeweilige Arraygrenze ermittelt werden soll.

FUNCTION F_CalcSum3DimArray : LREAL
VAR_IN_OUT
   arrData      : ARRAY[*, *, *] OF LREAL;
END_VAR
VAR
   nIndex1, nIndex2, nIndex3  : DINT;
END_VAR
F_CalcSum3DimArray := 0;
FOR nIndex1 := LOWER_BOUND(arrData, 1) TO UPPER_BOUND(arrData, 1) DO
  FOR nIndex2 := LOWER_BOUND(arrData, 2) TO UPPER_BOUND(arrData, 2) DO
    FOR nIndex3 := LOWER_BOUND(arrData, 3) TO UPPER_BOUND(arrData, 3) DO
      F_CalcSum3DimArray := F_CalcSum3DimArray + arrData[nIndex1, nIndex2, nIndex3];
    END_FOR
  END_FOR
END_FOR

Bei dem Aufruf kann ein beliebiges dreidimensionales Array von LREAL-Werten an die Funktion übergeben werden.

PROGRAM MAIN
VAR
  array01    : ARRAY[1..2, 3..4, 5..6] OF LREAL := [16.1, 34.1, 4.1, 43.1, 35.1, 2.1, 65.1, 16.1];
  lrSum01    : LREAL;
END_VAR
lrSum01 := F_CalcSum3DimArray(array01);

Beispiel 3 (TwinCAT 3.1.4020)

Somit lassen sich auch komplexere Aufgaben flexibel umsetzen ohne das auf Pointerarithmetik zurückgegriffen werden muss.

Dieses soll zum Schluss an einem Funktionsblock gezeigt werden, der zwei Matrizen miteinander multipliziert. Die Größen der Matrizen sind variabel:

METHOD PUBLIC Multiplication : BOOL
VAR_IN_OUT
  arrayA     : ARRAY[*, *] OF DINT;
  arrayB     : ARRAY[*, *] OF DINT;
  arrayX     : ARRAY[*, *] OF DINT;	
END_VAR
VAR
  nIndex1, nIndex2, nIndex3, nIndex4   : DINT;
END_VAR;
FOR nIndex1 := LOWER_BOUND(arrayA, 1) TO UPPER_BOUND(arrayA, 1) DO
  FOR nIndex2 := LOWER_BOUND(arrayB, 2) TO UPPER_BOUND(arrayB, 2) DO
    nIndex4 := 0;
    FOR nIndex3 := LOWER_BOUND(arrayA, 2) TO UPPER_BOUND(arrayA, 2) DO
      nIndex4 := nIndex4 + arrayA[nIndex1, nIndex3] * arrayB[nIndex3, nIndex2];
    END_FOR;
    arrayX[nIndex1, nIndex2] := nIndex4;
  END_FOR;
END_FOR;

Die Methode kann mit unterschiedlich großen Arrays aufgerufen werden.

PROGRAM MAIN
VAR
  fbMatrix     : FB_Matrix;
  arrayA1      : ARRAY[1..2, 1..2] OF DINT := [1, 2, 3, 4];
  arrayB1      : ARRAY[1..2, 1..2] OF DINT := [5, 6, 7, 8];
  arrayX1      : ARRAY[1..2, 1..2] OF DINT;
	
  arrayA2      : ARRAY[1..3, 1..3] OF DINT := [1, 2, 3, 4, 5, 6, 7, 8, 9];
  arrayB2      : ARRAY[1..3, 1..3] OF DINT := [5, 6, 7, 8, 10, 11, 12, 13, 14];
  arrayX2      : ARRAY[1..3, 1..3] OF DINT;				
END_VAR
fbMatrix.Multiplication(arrayA1, arrayB1, arrayX1);
fbMatrix.Multiplication(arrayA2, arrayB2, arrayX2);

Beispiel 4 (TwinCAT 3.1.4020)


Jürgen Gutsch: How to continuously deploy a ASP.​NET Core 1.0 web app to Microsoft Azure

We started the first real world project with ASP.NET Core RC2 a month ago and we learned a lot of new stuff around ASP.NET Core

  • Continuous Deployment to an Azure Web App
  • Token based authentication with Angular2
  • Setup Angular2 & TypeScript in a ASP.NET Core project
  • Entity Framework Core setup and initial database seeding

In this post, I'm going to show you how we setup a continuous deployment stuff for a ASP.NET Core 1.0 project, without tackling TypeScript and Angular2. Please Remember: The tooling around .NET Core and ASP.NET Core is still in "preview" and will definitely change until RTM. I'll try to keep this post up-to-date. I wont use the direct deployment to an Azure Web App from a git repository because of some reasons, I [mentioned in a previous post] .

I will write some more lines about the other learned stuff in one of the next posts.

Let's start with the build

Building is the easiest part of the entire deployment process. To build a ASP.NET Core 1.0, solution you are able to use MSBuild.exe. Just pass the solution file to MSBuild and it will build all projects in the solution.

The *.xproj files use specific targets, which will wrap and use the dotnet CLI. You are also able to use the dotnet CLI directly. Just call dotnet build for each project, or just simpler: call dotnet build in the solution folder and the tools will recursively go threw all sub-folders, to look for project.json files and build all the projects in the right build order.

Usually I define an output path to build all the projects into a specific folder. This makes it a lot easier for the next step:

Test the code

Some months ago, I wrote about unit testing DNX libraries (Xunit, NUnit). This didn't really change in .NET Core 1.0. Depending on the Test Framework, a test library could be a console application, which can be called directly. In other cases the test runner is called, which gets the test libraries passed as arguments. We use NUnit to create our unit tests, which doesn't provide a separate runner yet for .NET Core. All of the test libraries are console apps and will build to a .exe file. So we are searching the build output folder for our test libraries and call them one by one. We also pass the test output file name to that libraries, to get detailed test results.

This is pretty much all to run the unit tests.

Throw it to the clouds

Deployment was a little more tricky. But we learned how to do it, from the Visual Studio output. If you do a manual publish with Visual Studio, the output window will tell you how the deployment needs to be done. This are just two steps:

###1. publish to a specific folder using the "dotnet publish" command We are calling dotnet publish with this arguments:

Shell.Exec("dotnet", "publish \"" + webPath + "\" --framework net461 --output \"" + 
    publishFolder + "\" --configuration " + buildConf, ".");
  • webPath contains the path to the web project which needs to be deployed
  • publishFolder is the publish target folder
  • buildConf defines the Debug or Release build (we build with Debug in dev environments)

###2. use msdeploy.exe to publish the complete publish folder to a remote machine. The remote machine in our case, is an instance of an Azure Web App, but could also be any other target machine. msdeploy.exe is not a new tool, but is still working, even with ASP.NET Core 1.0.

So we just need to call msdeploy.exe like this:

Shell.Exec(msdeploy, "-source:contentPath=\"" + publishFolder + "\" -dest:contentPath=" + 
    publishWebName + ",ComputerName=" + computerName + ",UserName=" + username + 
    ",Password=" + publishPassword + ",IncludeAcls='False',AuthType='Basic' -verb:sync -" + 
    "enablerule:AppOffline -enableRule:DoNotDeleteRule -retryAttempts:20",".")
  • msdeploy containes the path to the msdeploy.exe which is usually C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe.
  • publishFolder is the publish target folder from the previous command.
  • publishWebName is the name of the Azure Web App name, which also is the target content path.
  • computername is the name/URL of the remote machine. In our case "https://" + publishWebName + ".scm.azurewebsites.net/msdeploy.axd"
  • username and password are the deployment credentials. the password is hashed, as in the publish profile that you can download from Azure. Just copy paste the hashed password.

conclusion

I didn't mention all the work that needs to be done to prepare the web app. We also use Angular2 with TypeScript. So we also need to get all the NPM dependencies, we need to move the needed files to the wwwroot folder and we need to bundle and to minify all the JavaScript files. This is also done in our build & deployment chain. But in this post, it should be enough to describe just the basic steps for a usual ASP.NET Core 1.0 app.

Manfred Steyer: Unterlagen von Session zum Upgrade von AngularJS 1.x auf Angular 2 von der DWX 2016 in Nürnberg

Nachfolgend meine Unterlagen von der Session zum Upgrade von AngularJS 1.x auf Angular 2 von der DWX 2016 in Nürnberg:

Manfred Steyer: Authentication in Angular 2 with OAuth2, OIDC and Guards for the newest new Router [English Version]

The new router for Angualr 2 provides so called Guards to influence routing. Those are services with methods that are called when the router activates or deactivates a route. The names of this methods are canActivate and canDeactivate. If such a method returns true, the router performs the current routing-action; otherwise it skips it. Furthermore, those methods can return an Observable<boolean> to postpone this decision.

In in my post here I've showed with an example how to use canDeactivate. It displays a warning when the user tries to exit a route and gives them the option to decide to stay.

This post shows how an application can use canActivate to keep an unauthenticated or unauthorized user away from specific routes. This isn't really about security, cause in browser-based applications security has to be implemented at server-side. Rather it's about usability cause it gives the application the possibility to ask the user to login in such cases. The whole source code of this sample can be found here. Besides Guards it also uses the security standards OAuth 2 and OpenId Connect (OIDC) to decouple the authentication and authorization from the application.

Preperation

To use OAuth 2 and OIDC, the here described sample uses my implementation, which can be installed via npm:

npm install angular2-oauth2 --save

After downloading this library has to import the OAuthService and create a provider for it. This provider is passed to bootstrap in this sample:

import { OAuthService } from 'angular2-oauth2/oauth-service';
[...]

var APP_PROVIDERS = [
  OAuthService
];

var providers = [
  APP_PROVIDERS,
  HTTP_PROVIDERS,
  [...]
];

bootstrap(AppComponent, providers);

The top level component can be used to configure the OAuthServices. The settings in the next sample point to an OAuth2/OIDC Auth Server that is available online an can be used for testing:

import { Component } from '@angular/core'
import { Router, ROUTER_DIRECTIVES } from '@angular/router'
import { HomeComponent} from './home/home.component';
import { OAuthService} from 'angular2-oauth2/oauth-service';

@Component({
    selector: 'flight-app',
    directives: [ROUTER_DIRECTIVES],
    template: require('./app.component.html')
})
export class AppComponent {

    constructor(private oauthService: OAuthService, private router: Router) {

        this.oauthService.loginUrl = "https://steyer-identity-server.azurewebsites.net/identity/connect/authorize"; //Id-Provider?
        this.oauthService.logoutUrl = "https://steyer-identity-server.azurewebsites.net/identity/connect/endsession?id_token={{id_token}}";
        this.oauthService.redirectUri = window.location.origin + "/index.html";
        this.oauthService.clientId = "spa-demo";
        this.oauthService.scope = "openid profile email voucher";
        this.oauthService.issuer = "https://steyer-identity-server.azurewebsites.net/identity";
        this.oauthService.setStorage(localStorage);
        this.oauthService.oidc = true;

        this.oauthService.tryLogin({});


    }
}

The method tryLogin checks, whether the app has got security tokens via the hash-fragment of the URL. It parses those tokens and extracts information of the current user.

In cases where this information is used for security-relevant procedures, the app has to validate the token. This is especially the case in hybrid and native apps that use it to access local resources. The following sample uses a callback to validate the token. For this, it calls a web api, that checks its signature:

this.oauthService.tryLogin({
    validationHandler: context => {
        var search = new URLSearchParams();
        search.set('token', context.idToken); 
        search.set('client_id', oauthService.clientId);
        return http.get(validationUrl, { search }).toPromise();
    }
});

Login

To redirect the user to the login-form of the Auth Server, the app has only to call the method initImplicitFlow that is provided by the OAuthService.

The method login in the following sample shows this. The method logout logs off the current user. For this purpose it deletes the saved tokens. If the service has been initialized with a logout url, it also redirects the user to this URL:

import { Component } from '@angular/core';
import { OAuthService} from 'angular2-oauth2/oauth-service';

@Component({
    selector: 'home',
    template: require('./home.component.html')
})
export class HomeComponent {

    constructor(private oauthService: OAuthService) {
    }

    public login() {
        this.oauthService.initImplicitFlow();
    }

    public logout() {
        this.oauthService.logOut();
    }

    public get userName() {

        var claims = this.oauthService.getIdentityClaims();
        if (!claims) return null;

        return claims.given_name;
    }

}

In addition to that, the getter userName tries to find out the user's first-name. For this, it accesses the claims that the library found within the security-token. The template of this component binds to those properties:

<h1 *ngIf="!userName">Welcome!</h1>
<h1 *ngIf="userName">Hello, {{userName}}!</h1>
<p>Welcome to this demo-application.</p>
<p>
    <button (click)="login()" class="btn btn-default">Login</button>
    <button (click)="logout()" class="btn btn-default">Logout</button>
</p>    
<p>
    Username/Passwort: max/geheim
</p>

Keeping away unauthorized users with Guards

To keep unauthorized users away from some routes the application can use guards. The following sample shows an implementation for this. Its just an Angular-2-Service that implements CanActivate and receives the OAuthService by the means of dependency injection.

The interface defines a method canActivate. The presented implementation checks, whether there are the necessary security tokens. Those are an Access-Token (OAuth2) as well as an Id-Token (OpenId Connect). If there are both, it returns true to signal the router that the component in question can be activated. Otherwise it skips the current routing-action by returning false:

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import { OAuthService} from 'angular2-oauth2/oauth-service';
import { Injectable} from '@angular/core';

@Injectable()
export class FlightBookingGuard implements CanActivate {

    constructor(private oauthService: OAuthService) {
    }

    canActivate(
        route: ActivatedRouteSnapshot, 
        state: RouterStateSnapshot) {

            var hasIdToken = this.oauthService.hasValidIdToken();
            var hasAccessToken = this.oauthService.hasValidAccessToken();

            return (hasIdToken && hasAccessToken);
    }
}

The parameters of canActivate inform about the current route as well as about the requested route.

In addition to that, the guard has to be registered with the property canActivate in the routing-configuration. This property does not directly point to the guards to use but to tokens that can be used to request the guards via DI:

import { RouterConfig, provideRouter } from '@angular/router';
import { HomeComponent} from './home/home.component';
import { FlightSearchComponent} from './flight-search/flight-search.component';
import { PassengerSearchComponent} from './passenger-search/passenger-search.component';
import { FlightEditComponent} from './flight-edit/flight-edit.component';
import { FlightBookingComponent} from './flight-booking/flight-booking.component';
import { FlightBookingGuard} from './flight-booking/flight-booking.guard';
import { FlightEditGuard} from './flight-edit/flight-edit.guard';
import { InfoComponent} from './info/info.component';
import { DashboardComponent} from './dashboard/dashboard.component';


const APP_ROUTES: RouterConfig = [
    {
        path: '/home',
        component: HomeComponent,
        index: true
    },
    {
        path: '/info',
        component: InfoComponent,
        outlet: 'aux'

    },
     {
        path: '/dashboard',
        component: DashboardComponent,
        outlet: 'aux'
    },    
    {
        path: '/flight-booking',
        component: FlightBookingComponent,
        canActivate: [FlightBookingGuard],
        children: [
            {
                path: '/flight-search',
                component: FlightSearchComponent
            },
            {
                path: '/passenger-search',
                component: PassengerSearchComponent
            },
            {
                path: '/flight-edit/:id',
                component: FlightEditComponent
            }
        ]
    }
];

In the current case, the guard is used as its token as well. Therefore, it can be directly mentioned within the provider configuration. This configuration also gets the provider for the router. For this, the sample calls the function provideRouter and passes the routing configuration to it:

const APP_PROVIDERS = [
  OAuthService
];

export const APP_ROUTER_PROVIDERS = [
    FlightBookingGuard,
    provideRouter(APP_ROUTES),
];

var providers = [
  APP_PROVIDERS,
  APP_ROUTER_PROVIDERS,
  HTTP_PROVIDERS
];

bootstrap(AppComponent, providers);

Calling a web api

To call a web api, the application has to pass the access-token. It can retrieve it from the method getAccessToken of the OAuthService. Usually, this Token has to be transmitted via the HTTP header Authorization:

public find(from: string, to: string) {
    var url = this.baseUrl + "/api/flight";

    var search = new URLSearchParams();
    search.set('from', from);
    search.set('to', to);

    var headers = new Headers();
    headers.set('Accept', 'text/json');
    headers.set('Authorization', 'Bearer ' + this.oauthService.getAccessToken())

    return new Observable((observer: Observer<Flight[]>) => {
        this.http
            .get(url, { search, headers })
            .map(resp => resp.json())
            .subscribe((flights) => {
                this.flights = flights;
                observer.next(flights);
            });
    });
}

The value Bearer specifies that the passed value is a so called bearer token. This is a token that gives the bearer - here the SPA - the rights that are associated with it.

Manfred Steyer: Unterlagen von Session zu Web APIs mit ASP.NET Core von der DWX 2016 in Nürnberg

Nachfolgend die Unterlagen zu meiner Session über Web APIs mit ASP.NET von der DWX 2016 in Nürnberg:

Manfred Steyer: Slides and Samples of my talk about the new newest router and Angular 2 at AngularCamp in Barcelona 2016

Below the slides and samples of my talk about the new newest router and Angular 2 at AngularCamp in Barcelona 2016.

The sample has been updated to Angular 2 RC 4 and Router Beta 4.

It shows:

  • Guards
  • Child-Routes
  • Aux-Routes

Downloads:

Fabian Deitelhoff: LEGO Mindstorms EV3: Kostenfreie Education Software

Heute habe ich eine sehr gute Nachricht für alle Fans des LEGO Mindstorms EV3🙂 Genauer gesagt betrifft es die Education Software, die LEGO neben der kostenfreien Home Edition angeboten hat. Bisher war diese Education Software, hauptsächlich für Schulen, AGs und andere Bildungseinrichtungen gedacht, kostenpflichtig. Preislich lag das Paket so um die 130 Euro pro Arbeitsplatz, wenn ich mich richtig erinnere. Oder circa 400 Euro für eine Schullizenz.

Diese Software ist jetzt kostenfrei erhältlich. Woher du dieses Softwarepaket bekommst, beschreibe ich kurz in diesem Beitrag.

Warum die Education Version letztendlich freigegeben wurde, kann ich gar nicht sagen. Mir ist es selber auch gar nicht aufgefallen. Ich wurde vom aufmerksamen Leser Jochen darauf hingewiesen. Wir hatten uns über die Programmierung des Elefanten-Modells unterhalten und in einer E-Mail schrieb er dann, dass er die Education Version herunterladen konnte. Vielen Dank an dieser Stelle noch mal für die Info! LEGO muss ziemlich still und heimlich diese Änderung vorgenommen haben. Denn mir sind auch keine anderen Infos wie Blogposts oder ähnliches darüber bekannt. Eine Pressemitteilung oder so ist mir ebenfalls nicht unter gekommen. Mir war vor 3-4 Wochen lediglich aufgefallen, dass die Education Version aus dem offiziellen LEGO Shop entfernt wurde. Dabei gedacht habe ich mir allerdings nicht viel.

Download der Software

Der Download der Education Version ist sehr simpel. Auf der Seite https://education.lego.com gibt es einen Downloadbereich. Der Link zum Downloadbereich funktioniert allerdings nur, wenn ihr im LEGO-Portal angemeldet seid. Dieser ist allerdings durch eine LEGO ID geschützt. Wer noch keine ID hat, kann über die Seite aber direkt eine erstellen oder sich eben mit einer vorhandenen einloggen (siehe Abbildung 1). Wenn die Links zu englischsprachigen Webseiten führen, kann die Sprache in der Regel oben rechts angepasst werden.

Abb. 1: Login mit einer vorhanden LEGO ID oder eine LEGO ID erstellen.

Abb. 1: Login mit einer vorhanden LEGO ID oder eine LEGO ID erstellen.

Ich hatte mir irgendwann mal eine LEGO ID erstellt. Ich glaube, um im LEGO Shop etwas zu bestellen. Das scheint die gleiche LEGO ID zu sein. Zu 100% sicher bin ich mir allerdings nicht. Eine LEGO ID zu erstellen ist allerdings auch kein großes Problem. Abgefragt werden einige Daten wie Benutzername, Passwort, Geburtsdatum und E-Mail Adresse. Danach ist der Account schon bereit.

Nach dem Login mit der LEGO ID stehen drei verschiedene Softwarepakete in einer Übersicht zur Verfügung (siehe Abbildung 2). Unter anderem auch die Software LME EV3-Software (45544), um die es hier geht. Hinter der Abkürzung LME verbirgt sich die LEGO Mindstorms Education Edition. Zusätzlich stehen auch Downloads für das neue Education WeDo 2.0 zur Verfügung.

Abb. 2: Downloads im Education Portal nach dem Login.

Abb. 2: Downloads im Education Portal nach dem Login.

Die jeweiligen Downloads lassen sich über die Weiter-Schaltflächen starten. Die führen auf die Produktseiten, wo dann die Downloads für Windows und Mac OS X bereitstehen.

Installation

Die Installationen sind denkbar einfach. Einfach die Installationspakete starten und die richtige Installations-Art auswählen. Die LEGO Mindstorms EV3 Education Edition steht in einer Schüler- und einer Lehrer-Version zur Verfügung. Diese Option ist schon bei der Installation auszuwählen (siehe Abbildung 3). Die parallele Installation beide Versionen ist nicht möglich. Also vorher gut überlegen, was wichtig ist. Privat installiere ich mir aktuell die Lehrer-Version.

Abb. 3: Unterschiedliche Versionen der LEGO Mindstorms EV3 Education Software.

Abb. 3: Unterschiedliche Versionen der LEGO Mindstorms EV3 Education Software.

Je nach System kann sich die Installation etwas hinziehen. Allerdings läuft sie vollautomatisch ab, so dass zwischendurch keine weiteren Entscheidungen getroffen werden müssen. Anschließend ist die Software gleich einsatzbereit (siehe Abbildung 4).

Abb. 4: Startbildschirm der LEGO Mindstorms EV3 Education Edition in der Lehrer-Version.

Abb. 4: Startbildschirm der LEGO Mindstorms EV3 Education Edition in der Lehrer-Version.

Die parallele Installation der Education- und der Home-Edition ist im Übrigen kein Problem. Zumindest konnte ich auf meinen Systemen bisher nichts feststellen. Allerdings ist ein gleichzeitiger Start nicht möglich. Ist also die Education-Edition gestartet, lässt sich die Home-Edition nicht noch zusätzlich starten. Auf meinem Windows 10 System gab es auch keine Fehlermeldungen oder einen sonstigen Hinweis, dass das nicht möglich ist. Es passierte einfach nichts.

Fazit

Ich finde den Schritt von LEGO, die Education-Edition kostenfrei zur Verfügung zu stellen, sehr gut. Warum es zu der Entscheidung gekommen ist kann ich nicht sagen. Vielleicht blieben die Verkäufe hinter den Erwartungen zurück. Meine Vermutung ist eher, dass die zusätzliche Software eine zu große Hürde war. Bildungsträger müssen eh schon tief in die Tasche greifen, wenn der LEGO Mindstorms EV3 eingesetzt werden soll. Dann auch noch Geld für die Software bezahlen war vermutlich nicht wenigen dann doch ein Tick zu viel.

Auf jeden Fall freue ich mich über diesen Schritt. Ich werde jetzt in meinen Kursen auf die Education-Version umsteigen und sie auch privat einsetzen.

Manfred Steyer: Slides and Samples of my Talk about modern Authentication with Angular 2, OAuth 2 and OIDC at AngularCamp 2016 in Barcelona

Below the slides and samples of my talk about modern authentication with Angular 2, OAuth 2 and OIDC at AngularCamp 2016 in Barcelona:

Manfred Steyer: Slides and Samples of my Talk about Databinding and Performance in Angular 2 at AngularCamp 2016 in Barcelona

Below the Slides and Samples of my Talk about Databinding and Performance in Angular 2 at AngularCamp 2016 in Barcelona:


Sven Hubert: Rückblick DWX 2016 – Microsoft HoloLens als Publikumsmagnet am Stand von AIT

Vom 20.6. bis zum 23.6.2016 traf sich die Entwickler Community wieder zur Developer Week (DWX) in Nürnberg. Die AIT präsentierte dort die Microsoft Datenbrille HoloLens. Diese war der Publikumsmagnet in der Ausstellung, die ihm Rahmen der Konferenz stattfand.

WP_20160622_10_57_50_Pro

Eröffnet wurde die Konferenz mit einer Keynote von Jürgen Appelo unter dem Titel „Managing for Happiness“. Diese Keynote können Sie Sich hier in voller Länge anschauen:

Auch die AIT war wieder mit vielen Vorträgen rund um Prozesse und Technologien in der Softwareentwicklung im Microsoft Umfeld vertreten:

Falls Sie Interesse an den Folien zu einem der Vorträge haben melden Sie Sich einfach bei franz.mattes@aitgmbh.de

In der begleitenden Ausstellung standen die AIT Consultants für vertiefende Fachgespräche zur Verfügung. Mit im Gepäck hatte die AIT auch zwei Exemplare der Microsoft HoloLens. AIT ist aktuell einer der wenigen Microsoft Entwicklungspartner in Europa denen Microsoft schon Entwickler Prototypen der HoloLens zugeteilt hat. Dies war deshalb für die meisten Besucher die erste Möglichkeit der HoloLens in freier Wildbahn zu begegnen, und so war es nicht verwunderlich, dass sie schnell zum Publikumsmagnet wurde. Jeder wollte sie sich einmal aufsetzen und in die Mixed Reality eintauchen. Bald war der Ausstellungsbereich deshalb mit Hologrammen an allen Ecken und Enden gefüllt. Die Besucher ohne Datenbrille mussten deshalb aufpassen, dass sie nicht auf virtuelle Hunde traten, oder mit einem Planeten oder Raumschiff kollidierten, als sie durch den Gang liefen. Mit den ersten Kunden führen wir inzwischen schon Gespräche über den Einsatz der HoloLens in deren Geschäftsumfeld, z.B. als Assistenzsystem in der Fertigung. Wenn auch Sie Projektideen in ihren Umfeld für die HoloLens haben können sie sich jederzeit bei mir melden: franz.mattes@aitgmbh.de. Wir können dann gerne darüber sprechen, wie wir Sie in dieser neuen Technologie unterstützen können.

WP_20160621_16_28_19_Pro

IMG_5678

IMG_5670

IMG_5669

IMG_5681

IMG_5682

 

Manfred Steyer: Slides and Case Study from my talk about Progressive Web Apps with Angular 2 at AngularCamp in Barcelona 2016

Below you find the slides and the Case Study from my talk about Progressive Web Apps with Angular 2 at AngularCamp in Barcelona 2016.

The Case Study shows:

  • Caching with Service Worker and the Service Worker Toolbox
  • Storing data with PouchDB (which uses IndexedDb, WebDb or LocalStorage)
  • AppShell Pattern with Caching to quickly provide value to the user
  • Web App Manifest and a Fallback using Meta-Tags to install the App to the Home Screen
  • Background Synchronisation with Service Workers
  • Push Notifications with Service Worksers
Downloads:



Manfred Steyer: Authentifizierung in Angular 2 mit OAuth2, OIDC, dem neuen Router und Guards

Der neue Router für Angular 2 bietet mit sogenannten Guards der SPA die Möglichkeit, das Routing zu beeinflussen. Dabei handelt es sich um Services, deren Methoden der Router beim Aktivieren bzw. Deaktivieren von Routen aufruft. Diese Methoden nennen sich sinngemäß canActivate und canDeactivate. Durch das Retournieren eines booleans können sie angeben, ob die jeweilige Aktion tatsächlich erlaubt ist. Zusätzlich können sie auch ein Observable<boolean> zurückliefern, um diese Entscheidung hinauszuzögern. Empfänge der Router über dieses Observable den Wert true, führt er die jeweilige Routingaktion aus. Empfängt er hingegen false, bricht er diese ab.

In meinem Beitrag hier habe ich anhand eines Beispiels die Nutzung von canDeactivate beschrieben. Es zeigt vor dem Verlassen einer Route eine Warnmeldung an und gibt dem Benutzer die Möglichkeit, seine Entscheidung zu revidieren.

Dieser Beitrag zeigt, wie eine Anwendung mit canActivateunberechtigte Benutzer von bestimmten Routen fernhalten kann. Dies dient weniger der Sicherheit, zumal Sicherheit bei Browser-basierten SPAs immer im Backend zu realisieren ist. Vielmehr dient dies der Benutzerfreundlichkeit, da hierdurch die Anwendung den Benutzer im Fall des Falls zur Anmeldung auffordern kann. Der gesamte Quellcode des hier präsentierten Beispiels findet sich hier. Es nutzt neben dem Guard-Konzept auch die Security-Standards OAuth 2 und OpenId Connect (OIDC), um die Authentifizierung und Autorisierung von der Anwendung zu entkoppeln und Single-Sign-On zu ermöglichen.

Vorbereitung

Zunächst benötigt man eine Bibliothek, die OAuth 2 und OIDC implementiert. Das hier betrachtete Beispiel nutzt meine Implementierung, welche via npm zur Verfügung steht:

npm install angular2-oauth2 --save

Danach ist der von dieser Bibliothek bereitgestellte OAuthService zu importieren und beim Bootstrapping der Anwendung zu berücksichtigen:

import { OAuthService } from 'angular2-oauth2/oauth-service';
[...]

var APP_PROVIDERS = [
  OAuthService
];

var providers = [
  APP_PROVIDERS,
  HTTP_PROVIDERS,
  [...]
];

bootstrap(AppComponent, providers);

Zum Konfigurieren des OAuthServices bietet sich der Konstruktor der Top-Level-Component an. Die nachfolgend eingerichteten Einstellungen verweisen auf einen OAuth2/OIDC-Auth-Server, den ich zu Testzwecken in der Cloud zur Verfügung stelle:

import { Component } from '@angular/core'
import { Router, ROUTER_DIRECTIVES } from '@angular/router'
import { HomeComponent} from './home/home.component';
import { OAuthService} from 'angular2-oauth2/oauth-service';

@Component({
    selector: 'flight-app',
    directives: [ROUTER_DIRECTIVES],
    template: require('./app.component.html')
})
export class AppComponent {

    constructor(private oauthService: OAuthService, private router: Router) {

        this.oauthService.loginUrl = "https://steyer-identity-server.azurewebsites.net/identity/connect/authorize"; //Id-Provider?
        this.oauthService.logoutUrl = "https://steyer-identity-server.azurewebsites.net/identity/connect/endsession?id_token={{id_token}}";
        this.oauthService.redirectUri = window.location.origin + "/index.html";
        this.oauthService.clientId = "spa-demo";
        this.oauthService.scope = "openid profile email voucher";
        this.oauthService.issuer = "https://steyer-identity-server.azurewebsites.net/identity";
        this.oauthService.setStorage(localStorage);
        this.oauthService.oidc = true;

        this.oauthService.tryLogin({});


    }
}

Der Aufruf der Methode tryLogin prüft, ob die Anwendung über das Hash-Fragment Security-Token empfangen hat. Sie parst diese Token und entnimmt Informationen über den Benutzer. Falls diese Informationen sicherheits-kritisch sind, muss die Anwendung das Token noch validieren. Dies ist vorallem bei hybriden und nativen Anwendungen, die diese Daten zum Zugriff auf lokale Ressourcen nutzen, der Fall. Das nachfolgende Beispiel nutzt dazu einen Callback, der sich zur Validierung an das Backend wendet:

this.oauthService.tryLogin({
    validationHandler: context => {
        var search = new URLSearchParams();
        search.set('token', context.idToken); 
        search.set('client_id', oauthService.clientId);
        return http.get(validationUrl, { search }).toPromise();
    }
});

Login

Um den Benutzer zur Login-Maske des Auth-Servers weiterzuleiten, ist lediglich die Methode initImplicitFlow des OAuthServices aufzurufen. Das nachfolgende Beispiel veranschaulicht dies mit der Methode login. Die Methode logout meldet den Benutzer ab. Dazu löscht sie alle Security-Token und falls die Anwendung dem Service eine Logout-Url mitgeteilt hat, leitet sie den Benutzer dorthin um:

import { Component } from '@angular/core';
import { OAuthService} from 'angular2-oauth2/oauth-service';

@Component({
    selector: 'home',
    template: require('./home.component.html')
})
export class HomeComponent {

    constructor(private oauthService: OAuthService) {
    }

    public login() {
        this.oauthService.initImplicitFlow();
    }

    public logout() {
        this.oauthService.logOut();
    }

    public get userName() {

        var claims = this.oauthService.getIdentityClaims();
        if (!claims) return null;

        return claims.given_name;
    }

}

Zusätzlich versucht der Getter userName den Vornamen des Benutzers zu ermitteln. Dazu greift er auf die Claims, welche die Bibliothek aus dem Security-Token entnommen hat, zu.

Das dazugehörige Template bindet sich an diese Eigenschaften und Methoden:

<h1 *ngIf="!userName">Welcome!</h1>
<h1 *ngIf="userName">Hello, {{userName}}!</h1>
<p>Welcome to this demo-application.</p>
<p>
    <button (click)="login()" class="btn btn-default">Login</button>
    <button (click)="logout()" class="btn btn-default">Logout</button>
</p>    
<p>
    Username/Passwort: max/geheim
</p>

Mit Guard unauthorisierte Benutzer fernhalten

Um anonyme oder nicht berichtige Benutzer von Routen fernzuhalten, kann sich die Anwendung auf Guards stützen. Das nachfolgende Beispiel zeigt eine entsprechende Implementierung. Es handelt sich dabei um einen Angular-2-Service, der CanActivate implementiert und sich den OAuthService injizieren lässt. Die vom Interface vorgegebene Methode canActivate prüft, ob die nötigen Security-Token vorliegen. Dabei handelt es sich um das von OAuth 2 definierte Access-Token sowie um das von OIDC ergänzte Id-Token. Wenn beide vorliegen und beide noch nicht abgelaufen sind, liefert sie true. Damit signalisiert sie dem Router, dass er die gewünschte Aktion ausführen darf. Ansonsten liefert sie false und bricht damit die Routing-Aktion ab:

import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import { OAuthService} from 'angular2-oauth2/oauth-service';
import { Injectable} from '@angular/core';

@Injectable()
export class FlightBookingGuard implements CanActivate {

    constructor(private oauthService: OAuthService) {
    }

    canActivate(
        route: ActivatedRouteSnapshot, 
        state: RouterStateSnapshot) {

            var hasIdToken = this.oauthService.hasValidIdToken();
            var hasAccessToken = this.oauthService.hasValidAccessToken();

            return (hasIdToken && hasAccessToken);
    }
}

Die von canActivate entgegengenommenen Parameter informieren über die aktuelle Route sowie über die angestrebte Routing-Aktion.

Der Guard ist dann noch in der Routing-Konfiguration in der Eigenschaft canActivate der jeweiligen Routen zu hinterlegen. Dabei handelt es sich zunächst lediglich um ein Token, welches später über einen Provider an einen Service zu binden ist:

import { RouterConfig, provideRouter } from '@angular/router';
import { HomeComponent} from './home/home.component';
import { FlightSearchComponent} from './flight-search/flight-search.component';
import { PassengerSearchComponent} from './passenger-search/passenger-search.component';
import { FlightEditComponent} from './flight-edit/flight-edit.component';
import { FlightBookingComponent} from './flight-booking/flight-booking.component';
import { FlightBookingGuard} from './flight-booking/flight-booking.guard';
import { FlightEditGuard} from './flight-edit/flight-edit.guard';
import { InfoComponent} from './info/info.component';
import { DashboardComponent} from './dashboard/dashboard.component';


const APP_ROUTES: RouterConfig = [
    {
        path: '/home',
        component: HomeComponent,
        index: true
    },
    {
        path: '/info',
        component: InfoComponent,
        outlet: 'aux'

    },
     {
        path: '/dashboard',
        component: DashboardComponent,
        outlet: 'aux'
    },    
    {
        path: '/flight-booking',
        component: FlightBookingComponent,
        canActivate: [FlightBookingGuard],
        children: [
            {
                path: '/flight-search',
                component: FlightSearchComponent
            },
            {
                path: '/passenger-search',
                component: PassengerSearchComponent
            },
            {
                path: '/flight-edit/:id',
                component: FlightEditComponent
            }
        ]
    }
];

Da in diesem Fall das Token gleichzetig auch der zu nutzende Service ist, ist dieser lediglich in die Provider-Konfiguration aufzunehmen. Zusätzlich kommen dort die Provider für den Router rein. Dazu kann die Anwendung die Methode provideRouter, welche die Routing-Konfiguration entgegennimmt, nutzen:

const APP_PROVIDERS = [
  OAuthService
];

export const APP_ROUTER_PROVIDERS = [
    FlightBookingGuard,
    provideRouter(APP_ROUTES),
];

var providers = [
  APP_PROVIDERS,
  APP_ROUTER_PROVIDERS,
  HTTP_PROVIDERS
];

bootstrap(AppComponent, providers);

Web API aufrufen

Beim Aufrufen von Web APIs ist das erhaltene Access-Token zu übergeben. Dieses stellt die Methode getAccessToken des OAuthServices zur Verfügung. Dieses Token ist über den Header Accept zu übergeben:

public find(from: string, to: string) {
    var url = this.baseUrl + "/api/flight";

    var search = new URLSearchParams();
    search.set('from', from);
    search.set('to', to);

    var headers = new Headers();
    headers.set('Accept', 'text/json');
    headers.set('Authorization', 'Bearer ' + this.oauthService.getAccessToken())

    return new Observable((observer: Observer<Flight[]>) => {
        this.http
            .get(url, { search, headers })
            .map(resp => resp.json())
            .subscribe((flights) => {
                this.flights = flights;
                observer.next(flights);
            });
    });
}

Der Wert Bearer gibt an, dass es sich beim übersendeten Wert um ein Bearer-Token handelt. Das sind Tokens, die seinem Überbringer - hier der SPA - die damit einhergehenden Rechte einräumen.

Johannes Renatus: T4 Template als Service/Proxybuilder für AngularJs TypeScript Services

Wenn man einen AngularJs HTTP Service erstellt der die Verbindung zum .NET Controller herstellen soll um Daten abzufragen oder zu speichern, handelt es sich immer um den “gleichen” boilerplate Code der geschrieben werden muss. Genau hier setzt mein T4 Template der Proxybuilder an und generiert die passenden AngularJs Services in JavaScript oder auch in TypeScript […]

Jürgen Gutsch: .NET Core 1.0 RTM and ASP.​NET Core 1.0 RTM was announced

Finally we get .NET Core 1.0 RTM and ASP.​NET Core 1.0 RTM. Yesterday Microsoft announces the release of .NET Core 1.0 and ASP.​NET Core 1.0.

Scott Hanselman posted a great summery about it: .NET Core 1.0 is now released! You'll find more detailed information about .NET Core 1.0 on the .NET Blog in the Post "Announcing .NET Core 1.0" and pretty much detailed information about ASP.​NET Core 1.0 in the .NET Web Development and Tools Blog in the post "Announcing ASP.NET Core 1.0"

Updating exiting .NET Core RC applications to the RTM, needs some attention. (Not as much as from RC1 to RC2, but there is a little bit to do). First of all: The Visual Studio 2015 Update 3 is needed, as pretty much mentioned in all of the Blog posts. To learn more about the need things to do, Rick Strahl posted a great and pretty detailed post about updating an existing application: Upgrading to ASP.NET Core RTM from RC2

Kay Giza [MS]: Welche Screen Capture Software verwende ich?

Ich werde von Zeit zu Zeit immer wieder gefragt, welche Tools ich für meine Präsentationen bei Vorträgen oder für meine Blogpostings benutze; so zuletzt auch auf der Developer Week. Dies nehme ich mal als Anlass dies zu skizzieren, insbesondere für alle Tekkis oder Menschen, die täglich dies brauchen könnten. Um es kurz zu machen, ich nutze generell... [... mehr in diesem Blogeintrag auf Giza-Blog.de]


This post is powered by www.Giza-Blog.de | Giza-Blog.de: RSS Feed
© Copyright 2006-2016 Kay Giza. All rights reserved. Legal

Holger Schwichtenberg: Microsoft veranstaltet wieder einen Technical Summit.

Im dritten Jahr in Folge veranstaltet Microsoft einen Technical Summit. Veranstaltungsort ist Darmstadt.

Karsten Kempe: Prozessanpassungen in Visual Studio Team Services – Work Item States

VSTSVor knapp zwei Monaten habe ich das erste Mal über Prozessanpassungen in Visual Studio Team Services geschrieben. Damals konnte man nur einfache Felder einem Work Item hinzufügen. Heute stelle ich Euch die Möglichkeit vor, wie man einen eigenen Prozess-Workflow mit Work Item States erzeugt.

Innerhalb eines individuellen Prozesses (wie man einen eigenen Prozess erzeugt, findet Ihr in den Basics), ist es seit kurzem möglich eigene Work Item Workflows oder auch Prozess-Workflows zu erzeugen. Dafür müssen in den Standard-Work Items neue Zustände definiert werden und/oder vorhandene Zustände ausgeblendet werden. Das Vorgehen hat rein gar nichts mehr mit dem Vorgehen beim Anpassen des Team Foundation Servers zu tun; keine XML-Dateien, kein WitAdmin, kein kompliziertes Handling mehr.

Wie beim Erstellen von neuen Feldern, wird in der Administrationsseite für Prozesse das zu verändernde Work Item ausgewählt und anschließend der Bereich „States“ selektiert. In den Details werden dann die einzelnen Zustände des Work Item Typen angezeigt.

Task Workflow

In meinem Task Work Item habe ich zum Beispiel den vorhandenen Initial-Zustand „ToDo“ ausgeblendet und durch den neuen Zustand „New“ ersetzt. Ausserdem habe ich den Zustand „Ready“ aufgenommen. Schön zu erkennen ist, dass die Zustände in Kategorien eingeteilt werden (Proposed, InProgress, Completed, Removed), die vergleichbar mit den bekannten Meta-Zuständen von Work Item Typen sind.

Wichtig: Vorhandene oder auch abgeleitete Zustände können nicht gelöscht werden, sondern nur aus dem Prozess ausgeblendet werden.

Das Erstellen eines neuen Zustands ist so einfach wie unspektakulär. Name vergeben, Kategorie und Farbe wählen und fertig.

Create State InReview

Durch die Veränderung der Zustände ist es nun auch erstmals möglich, die Spalten auf dem Task Board anzupassen, da diese sich ja nach dem Workflow des Task Work Items richten. Von vielen Nutzern sicherlich lang erwartet.

Task Board

Gut zu erkennen ist der neue Start-Zustand „New“ und der zusätzliche Zustand „Ready“.

Hinweis: Wer ein Work Item abändert, dass auf einem Kanban-Board angezeigt werden soll, darf sich nicht wundern, denn der neue State nicht automatisch auf dem Board angezeigt. Er muss erst über die Board-Einstellungen hinzugefügt werden.

Es ist natürlich noch nicht alles Gold was glänzt und vieles was im TFS funktioniert, geht im neuen Prozess-Modell des VSTS noch nicht. Es fehlen zum Beispiel noch das Bearbeiten der Zustandsübergänge, Zustands-Regeln und Workflow-Automatismen. Aber das Team arbeitet hart daran uns diese Feature so schnell wie möglich auch noch bereit zustellen.

Stay tuned!

[0] States customization on Team Services

[1] Prozessanpassungen in Visual Studio Team Services – einfache Felder

[2] Prozessanpassungen in Visual Studio Team Services – die Basics

Norbert Eder: Visual Studio 2015: Sprache ändern

Ich habe heute Visual Studio 2015 versehentlich in Deutsch installiert. Da ich allerdings Englisch bevorzuge, stellte sich die Frage, ob ich die Sprache ohne Neuinstallation ändern kann (denn von Haus aus unterstützt das Visual Studio nicht). Kann man:

Dazu gibt es ein Visual Studio 2015 Language Pack.

Nach der Installation findet sich ein neuer Eintrag in den Optionen: Internationale Einstellungen:

Visual Studio 2015 - Sprache wechseln

Visual Studio 2015 – Sprache wechseln

Damit die Änderungen wirksam werden ist Visual Studio neu zu starten.

Danke Dariusz für den Tipp.

The post Visual Studio 2015: Sprache ändern appeared first on Norbert Eder.

friends header

bloggers headline

links header

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