Archiv der Kategorie: .NET

Angular 2 mit webpack 2 mit ts, less, sass Loader für Anfänger in Visual Studio 2015 (Webpack Version – Beta 27)


Wäre die Welt nicht schön, wenn man sich nur mit Angular 2 beschäftigen könnte und nicht noch über das Deployment für den Live Betrieb nachdenken muss. Denn dann wäre die Standardinstallation von Angular 2 mit SystemJs völlig ausreichend. Wenn man allerdings seine erste kleine Angular 2 Anwendung erstellt hat, dann merkt man schnell das man sich noch mit dem Live Deployment beschäftigen muss. Denn wenn man die Anwendung startet dann dauert es bis zu 300++ Requests bevor die Seite komplett geladen ist und das ist nicht für Live geeignet.

Da ich bisher nur Angular 1 Seiten mit ASP.NET MVC umgesetzt habe, hatte ich bisher auch nicht viel Kontakt mit “import” Statements, gulp, grunt, webpack oder SystemJs – denn das hat bei Angular 1 alles Visual Studio für mich übernommen.

Jetzt stellte sich mir die Frage warum und weshalb brauche ich diesen neumodischen Kram eigentlich?

Bei Angular 2 kann ich hier leider nicht mehr auf Visual Studio zurückgreifen. Denn bei einer Umsetzung z.B. mit webpack muss klar unterscheiden zwischen dem Ordner “App” in dem wir die Anwendung schreiben (unsere TypeScript Dateien und HTML Templates liegen) und einem Ordner “wwwroot” in dem die “kompilierte” Anwendung (JavaScript Dateien) abgelegt wird, wenn diese fertig kompiliert wurde. Der Webserver ruft dann die “index.html” aus dem “wwwroot” Ordner auf.

Aber wie kompiliert man aus TypeScript Dateien, Less, Sass und HTML Templates eine richtige JavaScript Anwendung?

Mit SystemJs

Im Standardbeispiel von Angular 2 ist dies einfach gelöst, es gibt zum einen das direkte Übersetzen der TypeScript Dateien in JavaScript beim Speichern und SystemJs kümmert sich dann mit Hilfe der “systemjs.config.js” das alle passenden Dateien zur Laufzeit ausliefert werden und die Styles sind im besten Fall direkt auf der Seite eingebunden (300+ Requests).

Daher muss man sich um ein passendes “Bundling” der Dateien kümmern und dafür gibt es mehrere Möglichkeiten. Zum einen kann man gulp und grunt verwenden und die passenden Deployscripte schreiben oder man verwendet npm Scripts mit webpack 2 und schreibt dafür die Deployscripte. Ich habe mich für die zweite Variante entschieden, da es sich dabei aktuell wohl um die bevorzugte Variante zum Bereitstellen von Angular 2 handelt und da es auf der Angular 2 Seite zumindest ein Beispiel für die Umsetzung mit webpack 1 gibt. Ich beziehe mich aber im meinem Blogpost auf die aktuelle Variante webpack Beta 27.

Hinweis zu “npm Scripts”: In der “package.json” in der alle abhängigen npm Pakete für das Projekt angegeben sind, gibt es auch noch die Möglichkeit Kommandozeilen Befehle für npm abzulegen die mit “npm run <scriptname>” ausgeführt werden können, im folgenden Beispiel z.B. “npm run start” wird das “start” Script ausgeführt.

Mit webpack

Also was macht webpack eigentlich und wie funktioniert das ganze dann?

Wenn man webpack verwendet, gibt es wie schon beschrieben ein Verzeichnis in dem man seinen Quellcode hat z.B. “App” hier liegen alle TypeScript Dateien und HTML Templates. Auch unsere “index.html” in dieser sind weder styles noch script Tags enthalten, all das fügt webpack später beim Buildprozess automatisch in die “index.html” ein.

image

Und dann gibt es noch ein Verzeichnis für die Kompilierten Dateien  z.B. “wwwroot” hier liegen dann alle übersetzten und zusammengefassten JavaScript Dateien und Styles – der Ordner wird NICHT mit in die Quellcodeverwaltung eingecheckt.

image

Webpack kümmert sich dann um “alles” d.h. aufgrund der “import” Anweisungen in unseren Dateien weiß webpack genau welche Dateien wir alle benötigen und welche in einer Datei zusammengefasst werden sollen.

Webpack im “Detail”

Für die Implementierung von Angular 2 mit webpack 2 gibt es ein sehr gutes Github repository an dem ich mich orientiert habe. Im Folgenden gehe ich daher nicht auf alle Details ein, sondern beschreibe eher die Probleme auf die ich gestoßen bin. Diese könnt Ihr z.B. oft in den Kommentaren der Quellcode Dateien nachlesen.

Für Visual Studio gibt es eine sehr gute Task Runner Extension für webpack, mit dieser kann man die webpack Tasks direkt in Visual Studio starten vom einfachen Build bis hin zum Webpackserver (dazu weiter unten mehr) und man muss nicht immer eine npm Konsole öffnen.

Allgemeine “App” Einstellungen

Damit nicht der komplette JavaScript Code in einer Datei landet, splittet man diese am besten auf:

  • polyfills.ts – damit die Anwendung auch in älteren Browsern funktioniert muss auch als erstes im Browser geladen werden
  • vendors.ts – Angular Framework und abhängige Komponenten
  • boot.ts – der Root unserer Anwendung

Ich verwende z.B. noch Twitter Bootstrap als globalen Style mit Less und evtl. noch andere Styles z.B. in Sass oder css direkt. Auch die Styles sollen von webpack übersetzt, minifiziert und in der “index.html” automatisch eingebunden werden.

Denn webpack bindet “NUR” die Dateien in den Build Prozess ein, die auch über ein “import” Statement in einer der Dateien polyfills, venders oder boot eingebunden sind oder von diesen mit “import” eingebunden werden.

Damit meine Bootstrap Styles global verfügbar sind habe ich mich für das Einbinden von bootstrap in die vendors entschieden.

Denn wenn man die Styles direkt in einer Komponente als “styleUrls” einbindet, sind diese durch Angular 2, in den Standardeinstellungen nur in der eingebundenen Komponente gültig – ViewEncapsulation.

Ausnahmen für das Einbinden nicht direkt über “import” bilden die “templateUrl” und die “styleUrls”, diese werden von den webpack Loadern erkannt und dann entsprechend geladen.

Webpack Bereitstellungsmöglichkeiten

Die Task Runner Extension für die webpack Bereitstellung in Visual Studio, kann mit einem Rechtklick auf die “webpack.config.js” mit “Taskausführungs-Explorer” geöffnet werden.

image

Es gibt verschiedene Möglichkeiten, wie man die Dateien für den “wwwroot” Ordner von webpack erstellen lassen kann.

  • Manuell, sobald man eine Änderung durchgeführt hat und diese ausprobieren möchte, kann man einfach unter “Run” sein Projekt für die passende Umgebung neu bauen lassen

image

und die Ausgabe könnte dann folgendermaßen aussehen

image

  • Oder man kann einen Watcher ausführen lassen, der das Webverzeichnis der aktuellen Anwendung überwacht und sobald Änderungen an Dateien vorgenommen wurde, wird das Paket automatisch neu gebaut, hier muss dann nur noch mit F5 der Browser aktualisiert werden um die neuen Änderungen auch zu sehen
  • Dann gibt es noch einen einfachen node.js express Webserver der die aktualisierten Dateien bereitstellen kann. Hier gibt es zwei unterschiedliche Modus um die Seite zu aktualisieren.
  • COLD – die Seite wird automatisch komplett neu geladen (wie in meinem Beispiel)
    • HOT – es werden nur die Teile ersetzt die sich geändert haben (HOT wird auch HMR genannt und steht für “Hot Module Replacement”)

Die “webpack.config.js”

Wenn man webpack einsetzt, dann muss SystemJs komplett aus dem Projekt entfernt werden, denn webpack übernimmt dann das Bereitstellen von Development Paketen und den Live (Production) Paketen.

Damit die Visual Studio Extension für webpack auch funktioniert, muss die Datei “webpack.config.js” im Root Verzeichnis der Webseite abgelegt werden.

Da es unterschiedliche Konfigurationen gibt, für Allgemeine Einstellungen, Produktionseinstellungen, Liveeinstellungen und Testeinstellungen wird die Konfiguration in mehrere Dateien aufgeteilt und in meinem Beispiel im Verzeichnis “Config” abgelegt. In der “web.config.js” wird nur ausgewertet welcher Wert als NODE_ENV übergeben wurde über den Aufruf des Kommandozeilenbefehls z.B. für development über den Webpack Taskplaner

cmd /c SET NODE_ENV=development&& webpack -d –color

und es wird dann die passende “webpack.dev.js” Datei aufgerufen.

Die jeweilige webpack Konfiguration, setzt sich dabei aus zwei Dateien zusammen, einer Datei die speziell für die jeweils aufgerufene Umgebung z.B. development (dev) => “webpack.dev.js” die Werte enthält und einer allgemeinen Konfiguration “webpack.common.js”, die für alle Bereitstellungsszenarien immer die gleichen Werte beinhaltet. Diese beiden Konfigurationsdateien werden dann mit Hilfe einer JavaScript Bibliothek von Webpack “webpackMerge” zusammengeführt.

Die “webpack.common.js”

In der Konfiguration wird angegeben welche Startdateien es gibt, in unserem Falle drei “polyfills”, “vendors” und “boot”. Dann gibt es die “module” Sektion in denen die Loader verwendet werden, die wir auch in der package.json entsprechend in den dev-dependencies angeben müssen. Da sich webpack 2 aktuell noch in einer Beta befindet, hatte ich auch entsprechende Probleme die Loader für Less und Sass zum Laufen zu bekommen (siehe Kommentar über dem jeweiligen Loader).

ACTHUNG: Bei den Style Loadern gibt es jeweils einen Loader für die „StyleUrls“ in den Componenten und dann gibt es noch einen Loader für die globalen Styles die direkt per „import“ eingebunden werden, denn beide brauchen unterschiedliche Loader. Bei den jeweiligen Loadern sind die Verzeichnise für die diese zuständig sind per „include“ und „exclude“ festgelegt.

Um die HTML Dateien kümmert sich der “angular2-template-loader” wichtig ist das diese in der “templateUrl” in der Component mit einem relativen Pfad angegeben werden und mit einem “./” starten wie z.B. “./app.component.html”. Was bedeutet die HTML Datei befindet sich im gleichen Verzeichnis wie die Komponente. Gleiches gilt für die “styleUrls”.

ACHTUNG: KEINE ES6 Anführungszeichen verwenden bei den URL Angaben, hier wird dann einfach nur der String ausgeben “./app.component.html” und NICHT das HTML Template.

Wenn ich das ganze richtig verstanden habe, dann kümmert sich der “raw-loader” um die HTML Dateien die der “angular2-template-loader” entsprechend “bereitgestellt” hat.

HINWEIS: Die HTML Dateien die in der Component angegeben werden, werden mit in die bereitgestellten JavaScript Dateien von webpack eingebettet und es gibt keine Extra Dateien dafür im Ausgabeordner. Die Styles werden dank des „ExtractTextPlugin“ in einer Extra Datei abgelegt.

Dann gibt es noch die Plugins, welche teilweise direkt von webpack bereitgestellt werden oder extra in den dev-dependencies mit angegeben werden.

Die Plugins kümmern sich z.B. darum das in der “index.html” auch die richtigen Scripte, Styles und base Url eingebunden werden (HtmlWebpackPlugin und ExtractTextPlugin). Denn im Produktionsmodus wird noch ein Hash mit an den Dateinamen der jeweiligen JavaScript oder Style Datei angefügt, damit nicht ausversehen alte Daten geladen werden. Aus diesem Grund können wir auch nicht direkt die Styles und Scripte in unserer “index.html” verlinken, sondern müssen diese von webpack einfügen lassen.

HINWEIS: Ich habe mich aktuell dazu entschieden bei den DevDependencies immer nur noch die Direkte Version zu verwenden ohne „^“ oder „~“ vor der Versionsnummer, denn wenn Ihr pech habt wie ich, dann wird z.B. TypeScript von Version 2.0.10 auf 2.1.14 angehoben und plötzlich funktioniert das Deployment nicht mehr da es Probleme mit dem „awesome-typescript-loader“ gibt. Vor allem sucht man den Fehler erst einmal bei sich selbst, bevor man daran denkt das node evtl. eine neuere Version gezogen haben könnte die nicht vollständig kompatibel zu allen anderen Paketen ist.

Die “webpack.dev.js”

Die speziellen dev Einstellungen für unsere Anwendung.

Wichtig ist hier z.B. der Wert für “output.publicPath”, denn der hier angegebene Wert wird als Basispfad vor alle Script und Style Tags in der “index.html” eingefügt. (siehe Kommentare in der beigefügten dev Konfiguration)

Daraus ergibt sich dann z.B. die folgende “wwwroot\index.html” wenn das ganze erfolgreich kompiliert wurde.

Hier kann man gut erkennen, das wir aktuell die Daten vom webpack Server holen, der auf Port 3000 lauscht, auch das können wir entsprechend in der “webpack.dev.js” einstellen.

Webpack Zusammenspiel mit Visual Studio

Ich habe zwar aktuell keine Backend Funktionen in .NET implementiert, aber Visual Studio dient aktuell nur noch als Backend um z.B. Daten aus der .NET Welt im Browser anzuzeigen. Im Development Modus laufen am Ende zwei Webserver. Einer im IIS der unsere Anwendung hostet und die “index.html” aus dem wwwroot aufruft und der webpack webserver der die aktuellen Scripte und Styles bereitstellt.

Im Zusammenspiel mit der folgenden RouteConfig

und dem einfachen HomeController für den Index Aufruf.

Wird kein “Views” Ordner mehr benötigt.

Beispiel “installieren”

  1. Webpack Taskrunner Extension für VS 2015 installieren und VS neustarten
  2. Das Projekt von GitHub laden und in VS 2015 öffnen (Achtung hier sind noch mehr Projekte enthalten, bitte darauf achten, das diese nicht mit gebaut werden sondern nur “Angular2MitWebpack2”.
  3. das Verzeichnis mit einer NPM Konsole öffnen und mit Hilfe von “npm install” alle Pakete installieren lassen
  4. Den Taskrunner öffnen und einmal das “Run – Development” ausführen lassen und danach dann “serve – Cold” starten
  5. Die Webseite starten, diese sollte jetzt funktionieren.

Quellen:

https://webpack.js.org/

https://github.com/AngularClass/angular2-webpack-starter

https://offering.solutions/articles/asp-net/how-to-set-up-angular-2-and-webpack-in-visual-studio-with-asp-net-core/

Advertisements

Meine lieblings C# 6 Sprachfeatures


Man freut sich immer darüber wenn C# neue Features hinzugefügt werden und hofft das man so viele wie möglich davon auch verwenden wird, denn die meisten vereinfachen einem das Programmieren und sparen Codezeilen ein. Außerdem kann man die neuen Features auch in älteren Projekten verwenden, wichtig ist nur das VS 2015 oder TFS 2015 für das Bauen der Projekte verwendet wird, denn es handelt sich um reine Compiler Features und nicht um Features die durch eine neue .NET Version eingeführt wurden. Aktuell verwende ich die folgenden neuen Features recht häufig, was in vielen Fällen meiner Meinung nach die Lesbarkeit des Codes klar verbessert.

1. String Interpolation anstatt String.Format

Wenn man ein “$” Zeichen vor einen String schreibt den man erstellen möchte kann man im String selbst mit Hilfe von “{varname}” geschweiften Klammern direkt auf Variablen zugreifen. Was wesentlich angenehmer ist wie String.Format, wo man jedes mal nachzählen musste ob man auch den Wert an der richtigen Stelle einfügt.

2. nameof Schlüsselwort

Mit Hilfe des nameof Schlüsselworts, bekommt man die Bezeichnung eines beliebigen Properties zurück was man übergibt. Dies was früher maximal durch Reflexion möglich oder in dem man einen String mit dem Namen selbst angelegt hat. Jetzt reicht dafür ein einfacher Aufruf aus.

3. Direktes Initialisieren von Properties ohne Konstruktor

In vielen einfachen Klassen initialisiere ich die Properties jetzt direkt ohne das ich einen Konstruktor verwende, was die Klasse kleiner macht und wie ich finde übersichtlicher, da man direkt sieht mit welchem Wert in Property initialisiert wird.

4. Elvis Operator “?” in Verkettungen

Die Verwendung des Fragezeichens “?” direkt in Komplexen Abfragen ohne das man zusätzliche “If” Statements benötigt, die prüfen ob der Wert Null ist.

Natürlich gibt es noch mehr features mit C# 6, aber diese verwende ich nur selten. Nur die oben genannten Features habe ich in meiner täglichen Arbeit aktiv mit eingebunden und möchte diese aktuell nicht mehr missen.

Angular 2 Services automatisch aus .NET Controller erstellen mit T4 Template


Ich habe den bereit schon einmal vorgestellten ProxyGenerator erweitert, so das jetzt auch die Generierung von Angular 2 Services aus .NET Controllern möglich ist.

Der .NET Controller wird wie gehabt über jeder Funktion mit dem passenden Attribut versehen “CreateAngular2TsProxy” und als ReturnType wird der jeweilige .NET Rückgabewert der JSON Funktion eingetragen.

Mit Hilfe des T4 Templates “ProxyGeneratorScript.tt” wird dann der folgende Strongly Typed Angular 2 Service erstellt

Das ganze kann im Detail auf der zugehörigen GitHub Seite nachgelesen werden und das Paket selbst kann man per NuGet installieren. Wichtig ist das dafür zusätzlich noch TypeLite zum Erstellen der Passenden TypeScript Interfaces für unsere .NET Typen verwendet wird und damit ist es auch erst möglich das der Service komplett typisiert erstellt werden kann.

Package Installer Extension für Visual Studio


Inzwischen sollte man auch als .NET Webentwickler mitbekommen haben, das es neben NuGet auch noch npm und weitere Paketmanager gibt. Hier gibt es wie auch bei NuGet eine Konsole, aber meist keine direkte Visual Studio Integration. In den meisten Fällen möchte man aber nur schnell ein Paket installieren und nicht erst in die Doku schauen welche Konsolenbefehle man dafür genau benötigt. Genau hier kommt jetzt die Package Installer Extension zum Einsatz.

image

Mit dem Package Installer kann man Bower, npm, TSD, Typings oder NuGet Pakete sehr einfach und schnell installieren.

Wenn die Visual Studio Extension einmal installiert ist, steht mit einem Rechtsklick auf das Projekt der Menüpunkt “Quick Install Package…” zur Verfügung.

image

Hier öffnet sich dann ein kleines Popup in dem man die Quelle auswählen kann und danach gibt man nur noch den Paketnamen an.

image

Und der Package Installer lädt das passende Paket herunter und legt auch die passende Konfigurationsdatei an wie z.B. “typings.json” oder “package.json”.

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 und in Verbindung mit TypeLite werden komplett typisierte Services erstellt.

Damit das ganze funktioniert muss man nur noch seine Controller Methoden mit einem passenden Attribut versehen z.B. “CreateAngularTsProxyAttribute”. Dann das Projekt kompilieren und das T4 Template “Scripts\ProxyGeneratorScript.tt” ausführen und schon werden die passenden AngularJs Service Funktionen erstellt. Aus dem folgenden .NET Controller

wird dann der volltypisierte AngularJs TypeScript Controller der vom T4 Template generiert wurde.

Das komplette Projekt findet Ihr auf GitHub inklusive einer ausführlichen Beschreibung und ein Beispielprojekt. Das fertige Paket gibt es auch bei NuGet.

Der Proxybuilder kann die folgenden Proxies erstellen, dafür wird jeweils nur das passende Proxybuilder Attribut benötigt:

  • AngularJs pure JavaScript Services
  • AngularJs TypeScript Services voll Typisiert und nur in Verbindung mit TypeLite zu verwenden. TypeLite erstellt Interfaces von unseren .NET Klassen in TypeScript, die der Proxybuilder dann verwendet für Übergabe- und Rückgabewerte.
  • jQuery pure JavaScript Services
  • jQuery TypeScript Services voll Typisiert und nur in Verbindung mit TypeLite.

Wenn Ihr Fragen oder Erweiterungswünsche habt, dann bitte auf GitHub als Issue eintragen.

Angular 4 “Hello World” mit Visual Studio 2015 Update 3, ASP.NET 4 und TypeScript (aktualisiert für Angular 4.0.3 Release)


Da es nicht jedem Entwickler vergönnt ist immer auf die neuesten Technologien zurückgreifen wie z.B. ASP.NET Core, dachte ich mir ich versuche es mal mit dem guten alten ASP.NET 4 und Angular 2. Aber das hat gedauert bis ich Angular 2 bei mir zum “Laufen” bekommen habe, denn es gibt für Angular 2 und den zugehörigen Abhängigkeiten kein NuGet Paket mehr. Denn leider scheint NuGet für viele JavaScript Bibliotheken an Bedeutung zu verlieren. Damit muss man auch in Visual Studio auf npm (Node Package Manager) und Konsorten zurückgreifen.

1. Erstellen einer ASP.NET 4 Anwendung

Als erstes erstellen man eine ASP.NET 4 Anwendung im Visual Studio und geht auf “File –> New –> Project” und wählt die “ASP.NET Web Application” aus.

image

Dann eine MVC Anwendung anlegen ohne Authentifizierung (enthält einfach weniger Code und die Authentifizierung wird in unserem Beispiel nicht benötigt).

image

2. NPM Konfiguration zu unserem Projekt hinzufügen

Da es leider kein NuGet Paket für Angular 2 gibt, muss man eine “package.json” im Root der Anwendung anlegen.

image

imageimage

welche Packages benötigt werden, findet man in der aktuellen Angular 2 Dokumentation, denn dabei handelt es sich nicht nur um eine einfache Angular 2 JavaScript Datei, sondern hier sind noch weitere Komponenten notwendig. Warum und weshalb kann man auch in der Dokumentation nachlesen. Aktuell sieht die Json Datei dann z.B. folgendermaßen aus

ACHTUNG: Ich habe zu den Abhängigkeiten die auf der Angular Seite angezeigt werden, noch die aktuelle “gulp” Version hinzugefügt (Warum erläutere ich weiter unten)

ACHTUNG: Wenn man von der Beta auf die RC Version aktualisiert, würde ich empfehlen den node_modules Ordner vorher einmal zu löschen, da Angular jetzt in einem anderen Order zu finden ist und sich sehr viel strukturell geändert hat.

ACHTUNG: Ich gebe inzwischen die Versionsnummern nur noch ohne „~“ und „^“ davor an. Denn damit hatte ich in der letzten Zeit vor allem bei den devDependencies immer wieder Probleme, das hier Pakete veröffentlicht wurden so das dass Projekt am ende nicht mehr funktioniert hat und wenn man „~“ und „^“ weglässt kann man sich „sicher“ sein das man genau die Pakete wieder bekommt und das alles noch funktioniert wie bisher.

Wenn man jetzt mit der rechten Maustaste auf die package.json geht, gibt es dort einen Punkt “Restore Packages”, mit diesem werden wie bei NuGet alle Pakete heruntergeladen für unsere package.json. In ein Verzeichnis mit dem Namen “node_modules”. Das Verzeichnis wird NICHT unserem Projekt hinzugefügt und kann nur angezeigt werden, wenn man versteckte Dateien einblendet.

image

Wenn Ihr glück habt, werden alle Dateien heruntergeladen. Das sieht man, wenn man die Output Konsole öffnet und “Bower/npm” als Ausgabe anzeigen lässt, wenn hier keine Fehler auftreten ist alles OK.

image

Bei mir kam es hier aber zu einem Fehler, da Visual Studio seine eigene Installation von npm mit sich bringt, diese aber zum Herunterladen der Komponenten “veraltet” war, musste ich die neuste Version von npm installieren und dann im Visual Studio eintragen. Dafür geht man in die QuickLaunch box rechts oben und tippt “External Web Tools” ein und wählt den Eintrag aus. (siehe auch Visual Studio 2013/2015 bereitgestellte nodejs Version veraltet)

image

In “External Web Tools” dann den Pfad zum aktuellen nodejs Verzeichnis hinzufügen und den Eintrag an den Anfang verschieben. Dann am besten Visual Studio noch einmal neu starten und versuchen das “Restore Packages” noch einmal auszuführen, diesmal hoffentlich ohne Fehler.

image

HINWEIS: Mit dem Update auf Angular 2 RC1 kam es bei mir zu einem weiteren Fehler und im Output Fenster für “Bower/npm” stand z.B. folgende Fehlermeldung:

npm ERR! 404 '@angular/http' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it

Ab der RC1 von Angular 2 ist wichtig das man mindestens NodeJs 6.x installiert hat und NPM mindestens Version 3.8.9 installiert hat, denn nur dann werden die neuen Packages erkannt und können heruntergeladen werden. Leider geht bei mir zumindest die IntelliSense für die Erkennung der Versionsnummern im package.json für die Angular Pakete mit dem “@” davor nicht mehr.

3. Wozu ist überhaupt dieses “gulp” da?

Wir haben zwar unsere Module alle heruntergeladen die in der package.json eingetragen waren, aber diese liegen in einem eigenen Verzeichnis “node_modules” in dem noch viel mehr Dateien liegen. Mit gulp kann man eine einen “Task” erstellen der z.B. vor jedem starten des Projekts alle für uns wichtigen JavaScript oder Stylesheet Dateien in den lokalen Scripts oder Styles Ordner kopiert oder temporäre Dateien löscht oder Minifizierungen durchführt. Dafür muss im Root unserer Webseite eine “gulpfile.js” angelegt werden mit dem folgenden Inhalt.

Wenn man jetzt mit der rechten Maustaste auf die “gulpfile.js” klickt, gibt es einen Punkt “Task Runner Explorer”, diesen bitte anklicken.

image

und es öffnet sich ein neues “Fenster”. Wenn dies noch “leer” aussieht, dann am besten Visual Studio neu starten.

image

Nach dem Neustart sollte das ganze folgendermaßen aussehen

image

Mit der rechten Maustaste auf “moveToScripts” kann man das ganze auch direkt einmal ausführen und wenn das Ausführen erfolgreich war, können wir in unseren Scripts Ordner gehen und hier alle Dateien anzeigen lassen, denn diese wurden nicht dem Projekt hinzugefügt, sondern nur in den Ordner kopiert.

image

image

Ich habe diese dann in das Projekt eingebunden mit “Include In Project”

image

Update Angualar 2.1.1: In der neuesten Version, kopiere ich die Dateien aktuell nicht mehr per Gulp ins lokale Scripts Verzeichnise, sondern verweise direkt auf die Pfade im node_modules ordner, da dieser sowieso vorhanden sein muss und dies erspart uns vorerst etwas Konfigurationsaufwand. Für den Produktivmodus wäre es aber mit sicherheit besser diese per Bundle auszuliefern.

3.1 TypeScript Einstellungen (veraltet ab VS 2015 Update 3)

Am besten ist es wenn man die neuste Version von TypeScript installiert hat, denn bei mir gab es erst ab Version 1.8 keine Probleme mehr, obwohl eigentlich 1.5 ausreichen sollte. Dann müssen wir eine erste TypeScript Datei in unserem Projekt hinzufügen, am besten unter: “ScriptsApp/app.modules.ts”.

scriptappordner

Jetzt öffnen wir die Einstellungen (Properties) der Webseite und schauen uns die “TypeScript Build” Einstellungen an, jetzt sollten die Einstellungen auch in der csproj generiert sein.

image

Ich habe es leider nicht hinbekommen in der alten Visual Studio Version 2015 Update 2 TypeScript über eine “tsconfig” zu konfigurieren in der Neuesten Version von VS 2015 Update 3 ist dies auch mögloch über die tsconfig (weiter unten eine genauer Erläuterung dazu).

Da Angular 2 mehrere “experimentelle TypeScript Features” verwendet  die erst noch aktiviert werden müssen. Muss man die “csproj” Datei der Webseite bearbeiten, denn die Features die man benötigt, können nicht in den Einstellungen der Webseite eingestellt werden. Dafür muss die Webseite entladen werden mit “Unload Project”.

image

Danach kann man wieder mit der rechten Maustaste auf das entladene Projekt gehen und es bearbeiten mit “Edit …csproj”. Und in der csproj am besten nach “TypeScriptTarget” suchen und schon sieht man einen Block in dem einige TypeScript Einstellungen vorgenommen werden können.

image

Ich konnte mein Projekt mit Angular 2 erst erstellen, nach dem ich den folgenden Block mit Einstellungen für TypeScript eingefügt habe und alle anderen TypeScript Settings damit überschrieben habe.

sonst kam beim Erstellen der TypeScript Dateien immer der Fehler “module not found” und das Projekt konnte nicht kompiliert werden. Jetzt kann man die csproj wieder schließen und unser Projekt wieder laden.

TypeDefinitions für Angular 2 brauchen wir dem Projekt keine hinzufügen, diese scheint er sich über den “node_modules” Ordner (obwohl dieser ausgeblendet ist) bereits selbst zu suchen, denn dort sind bereits alle wichtigen TypeDefinitions mit enthalten (hierbei handelt es sich aber nur um meine aktuellen Beobachtungen, wenn hier jemand genaueres weiß warum das funktioniert, freue ich mich über einen Kommentar).

3.2 TypeScript Einstellungen über tsconfig.json

Ab Visual Studio 2015 Update 3 ist es auch möglich in älteren MVC Projekten auf die tsconfig.json zurückzugreifen und nicht mehr wie in 3.1  beschrieben über die Projekteinstellungen. Dafür muss im Root der Webseite, da wo auch die „package.json“ liegt eine „tsconfig.json“ angelegt werden mit dem folgenden Inhalt.

Wenn alles geklappt hat und man die Projekteigenschaften aufruft für die „TypeScript-Build“ Einstellungen, sollte hier  alles deaktiviert sein und angeben sein das mindetens eine „tsconfig.json“ gefunden wurde in der jetzt die Einstellungen konfiguriert werden.

typescriptbuildsettings

4.Typings installieren für Visual Studio (Veraltet ab TypeScript Version 2.0+)

Damit Visual Studio auch alle Typen erkennt, muss man noch die passende index.d.ts Datei hinzufügen. Und am einfachsten installiert man diese mit der Package Installer Extension, hier muss nur „Typings“ ausgewählt werden und „es6-shim“ eingetragen werden und schon werden die passenden Typings installiert.

image.png

Der Pfad zur index.d.ts Datei wird dann in der boot.ts entsprechend angegeben. Die von NPM hinzugefügten Dateien werden NICHT dem Projekt hinzugefügt.

image

4.1 Typings in Visual Studio ab TypeScript 2.0+

Sobald man TypeScript 2.0 oder höher verwendet, kann man auf die Typings „verzichten“ und diese werden direkt in der tsconfig.json eingestellt. Hier kommt bei „compileroptions“ das Property „lib“ hinzu. Bei lib handelt es sich um ein Enum in dem man die Umgebung angeben kann die in den TS Dateien bekannt gemacht werden soll, damit z.B: Promises erkannt werden. Wenn man zusätzlich auch noch bestimmte Typen benötigt die man über npm installiert hat wie z.B. jasmine mit „@types/jasmine“ dann gibtes noch ein neues Property „types“ hier kann man dann die customtypes noch angeben die in den TS Dateien bekannt sein sollen.

Daher wird auch in der „boot.ts“ kein Verweis mehr auf die „index.d.ts“ benötigt und kann entfernt werden. Ebenso kann die „typings.json“ und der Ordner „typings“ entfernt werden.

ACHTUNG es reicht nicht aus den Ordner „typings“ aus dem Projekt auszuschließen dieser muss auch im Filesystem entfernt werden, sonst kommt es zu Fehlern, das z.B. Promise bereits bekannt ist.

5. Angular 2 “Hello World App”

So jetzt nachdem wir unser Projekt entsprechend vorbereitet haben, können wir auch noch unsere Angular 2 Anwendung schreiben.

Dazu erstellen wir noch zwei TypeScript Dateien „boot.ts“ und „app.module.ts“ auch direkt im „ScriptsApp“ Verzeichnis.

scriptappordner

Der Inhalt der boot.ts sieht folgendermaßen aus.

HINWEIS: “./” vor mainApp gibt an das im aktuellen Verzeichnis nach der Datei gesucht werden soll.

Die „boot.ts“ Datei gilt als Einstieg in unsere Anwendung und ruft die „app.module.ts“ Datei auf in der alle wichtigen globalen Module, Componenten und Services definiert sind und die dann auch unsere Anwendung die „app.component“ enthält.

für die app.component.ts sieht der Code folgendermaßen aus und “my-app” ist der Selector mit dem wir unsere neue Komponente entsprechend anzeigen können.

ACHTUNG: Wenn man von Angular 2 Beta zur RC Updated müssen auch alle Pfade in den imports aller Projektdateien angepasst werden und aus “angular2” wird “@angular” z.B. aus “angular2/core” wird “@angular/core”.

Dann habe ich die _Layout.cshtml etwas aufgeräumt und nur noch die wichtigsten Einträge hinzugefügt, wie die Verweise auf unsere JavaScript Dateien und das Einrichten von SystemJs um unsere Dateien zu laden sowie unser neues Tag “my-app”.

Angular 2 selbst wird in den Scripts seit der RC nicht mehr direkt verlinkt, sondern dafür wird jetzt die SystemJs Konfiguration verwendet.

6. SystemJs konfigurieren

Damit Angular auch weiß wo er welche Module für Angular 2 zu finden sind, muss SystemJS noch konfiguriert werden. Ich habe dafür eine Datei mit dem Namen “systemjs.config.js” im Scripts Verzeichnis angelegt. In dieser Datei werden alle verwenden Angular 2 Module definiert und es wird angegeben wo diese zu finden sind. Ich habe diese im node_modules Ordner gelassen, denn im Beispiel auf der Angular 2 Seite wird es ebenfalls so gehandhabt. Mir ist hier aufgefallen, das die „systemjs.config.js“ jedes mal „anders“ aussieht und aufgeräumter wirkt, daher wenn Ihr Angular aktualisiert prüft auch nach ob Ihr evtl. die „systemjs.config.js“ mit anpassen müsst.

Hinweis: Für die Produktive Bereitstellung einer Angular 2 Anwendung sollte man z.B. webpack 2 verwenden, hier werden alle wichtigen Bibliotheken in eine JavaScript Datei zusammengefasst und nicht wie bei SystemJs 300+ Requests beim Aufrufen der Seite erzeugt. Ich habe dafür den folgenden Artikel erstellt „Angular 2 mit webpack 2 mit ts, less, sass Loader für Anfänger in Visual Studio 2015

Wenn man jetzt die Webseite startet, dann sollte das ganze funktionieren und im Browser z.B. folgendermaßen aussehen.

image

Wenn nichts angezeigt wird, am besten die Entwicklerkonsole öffnen und schauen was für ein Fehler angezeigt wird, diese sind wie ich finde inzwischen doch recht aussagekräftig, zumindest im Vergleich zu NG1.

HINWEIS: Es muss Resharper ab Version 2016.2 verwendet werden, da sonst die Componenten nicht erkannt werden oder die neuen Angular Tags im HTML nicht erkannt und werden und dann rot unterstrichen sind.

HINWEIS: Wenn Ihr „automatisch“ aus euren .NET WebAPI oder Controller Aufrufen einen Angular 2 Service erstellen wollt, dann versucht doch einmal den ProxyGenerator. Der besteht aus einem T4 Template mit dem Ihr voll typisierte Angular 2 Services erstellen könnt direkt aus den .NET Klassen.

Quelle:

http://www.mithunvp.com/angular-2-in-asp-net-5-typescript-visual-studio-2015/

https://yakovfain.com/2016/05/06/starting-an-angular-2-rc-1-project/

Das zugehörige Projekt auf meiner GitHub Seite sollte voll funktionsfähig sein. Aber bitte daran denken das man die passenden NPM Befehle noch ausführen muss für die Typings und den Package Restore für die package.json.

https://github.com/squadwuschel/Angular2Introduction/tree/master/Angular2HelloWorld

Alternativ gibt es noch eine etwas erweiterte Einführung in der auch der Ui-Router eingebunden ist und man sieht wie man einen Service einbindet.

https://github.com/squadwuschel/Angular2Introduction/tree/master/Angular2Introduction/Angular2Introduction

Updated from Angular 2.0 RC1 to RC2

Für das Update von RC1 auf RC2 habe ich lediglich die „package.json“ aktualisiert und die „systemjs.config.js“ an das Beispiel vom Angular Quickstart angepasst und schon sollte alles wieder funktionieren.

Updated from Angular 2.0 RC2 to RC3

Einfach nur die „package.json“ angepasst und die Pakete aktualisiert.

Updated from Angular 2.0 RC3 to RC4

Einfach nur die „package.json“ angepasst und die Pakete aktualisiert.

Updated from Angular 2.0 RC4 to RC5

Einfach nur die „package.json“ angepasst und die Pakete aktualisiert. Außerdem wurde das Beispiel um eine „appModule.ts“ Datei erweitert in der jetzt per „ngModule“ Decorator Globale Importe für das gesamte Projekt definiert werden können wie HTTP_PROVIDERS oder FormsModule für „(ngModule)“. Die Datei ist jetzt auch in der offiziellen Hello World Anwendung von Angular 2.0 vorhanden und ich habe mein Beispiel nur entsprechend angepasst.

Updated from Angular 2.0 RC5 auf Angular 2.0.0 Release

Die „package.json“ angepasst und die Pakete aktualisiert. Außerdem habe ich die Typings aktualisiert und es gibt jetzt keine „browser.d.ts“ Datei mehr, sondern eine „index.d.ts“ auf die für die passendne Typings verwiesen werden muss. Wenn man bereits ein größeres Beispiel hatte welches z.B. HTTP_PROVIDERS verwendete, kommt es zu einem Fehler denn diese gibt es nicht mehr, sondern nur noch das „HttpModule“. Außerdem gibt es in „@component“ nicht mehr den Verweis auf „directives“ die darin verwendet werden, sondern diese werden jetzt alle in ngModule eingetragen. Das Beispiel auf meiner GitHub Seite verwendet die ngModules bereits und definiert auch dort die passenden Components.

Update from Angular 2.0.0 auf 2.1.1 (31.10.2016)

Ich habe die tsconfig.json hinzugefügt um eine alternative für die TypeScript Kompillierung für Visual Studio 2015 ab Update 3 und älteren MVC Projekten zu zeigen. Außerdem habe ich eine komplet Neue Angular 2 Hello World Anwendung auf Github hinzugefügt.

Update (07.12.2016) – Es gibt es jetzt einen neuen Artikel der die Verwendung von Angular 2 mit Webpack 2 beschreibt und nicht mit SystemJs.

Update (28.02.2017) – package.json angepasst auf Angular 2.4.0 und eine neue Möglichkeit Typings in Visual Studio zu verwalten hinzugefügt – denn ab TypeScript 2.0 wird kein „typings“ Ordner mehr benötigt in Visual Studio.

Update (16.05.2017) – package.json angepasst auf Angular 4.0.3

ASP.NET MVC Custom Error Handler Attribute und Ajax Calls


Normalerweise, fange ich die meisten Fehler direkt im Code ab und habe in jedem Ajax Request ein erweitertes Response Model was immer von einer Basisklasse ableitet in dem ich Nachrichten oder Fehlermeldungen mit übergeben kann.

Sobald also bei einem Response Meldungen enthalten sind, dann werden diese z.B. von AngularJs per Interceptor ausgewertet und im UI angezeigt. Das klappt auch sehr gut so lange man ein “aufgeblähtes” Model zurückgeben möchte. Wenn ich aber nur Daten für ein Typeahead benötige, was nur eine List<string> zurückgeben soll, dann möchte ich hier nicht eine Extra Klasse anlegen die nur ein Property für die List<string> enthält, nur damit ich eine Fehlermeldung mit zurückgeben kann. Für diese Fälle habe ich jetzt den Custom Error Handler für mich entdeckt.

Der Custom Error Handler wird aufgerufen, sobald eine Exception auftritt die nicht abgefangen wird und bis zum Controller Aufruf durchgereicht wird. Hier wird die Exception dann abgefangen und man kann den Ajax Call entsprechend ändern der zurückgegeben werden soll und den Fehler zurückgeben z.B. in der von mir bevorzugten Struktur, damit der Interceptor den Fehler auch abfangen und anzeigen kann.

Code Custom Error Handler:

/// <summary>
/// Custom Error Handler der über der passenden Controller Funktion verwendet wird um unbehandelte Ausnahmen abzufangen.
/// </summary>
public class CustomErrorHandlerAttribute : HandleErrorAttribute
{
    public bool IsAjaxCall { get; set; }

    public override void OnException(ExceptionContext context)
    {
        if (IsAjaxCall)
        {
            context.ExceptionHandled = true;
            var jsonResult = new JsonResult();
            jsonResult.Data = new {Message = context.Exception.Message , MessageType = "Error"};
            jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            jsonResult.ExecuteResult(context);
        }
        else
        {
            // if not an ajax request, continue with logic implemented by MVC -&gt; html error page
            base.OnException(context);
        }
    }
}

Beispiel Controller Methode die einen Fehler verursacht:

[CustomErrorHandler(IsAjaxCall = true)]
public JsonResult AddJsEntryOnly(Person person)
{
    throw  new Exception("Beim Laden der Daten ist ein Fehler aufgetreten!");
    return Json(person, JsonRequestBehavior.AllowGet);
}

Wenn ich den Rückgabewert (Ajax Call)  jetzt im Browser in der Konsole ausgeben lasse steht da:

image