From fdaac4682635884e4acb346b8fa447913cdf2c09 Mon Sep 17 00:00:00 2001 From: Rex YE Date: Sat, 19 Nov 2016 23:35:34 +0000 Subject: [PATCH 01/23] in-progress-cookbook. --- .../ts/latest/cookbook/angular-dotnet-core.md | 295 ++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 public/docs/ts/latest/cookbook/angular-dotnet-core.md diff --git a/public/docs/ts/latest/cookbook/angular-dotnet-core.md b/public/docs/ts/latest/cookbook/angular-dotnet-core.md new file mode 100644 index 0000000000..584e9fc344 --- /dev/null +++ b/public/docs/ts/latest/cookbook/angular-dotnet-core.md @@ -0,0 +1,295 @@ +# Cookbook Introduction + +This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. +.NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. + +In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. + +# Prerequisite + +1. Install Visual studio 2015 Update 3 + +1. Install .NET Core Tools for visual studio 2015 + +1. Install .Net Core SDK + +1. Install Typescript 2 for visual studio 2015 + +1. Install Node.js Tools for visual studio 2015 (optional) + +# Create a new .NET Core Web Application + +* Select `File` | `New` | `Project` from the menu +* In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` +* Select `ASP.NET Core Web Application (.NET Core) template, give the project a name, and click OK. +* Select `Web Application` and click OK. Wait for visual studio to restore packages. + +# Create Configuration files for your Angular app. + +In the root folder, create `package.json` and `tsconfig.json` files. Populate them by pasting the contents below. + +Package.json +``` +{ + "name": "angular-dotnet-core", + "version": "1.0.0", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/angular/angular.io/blob/master/LICENSE" + } + ], + "dependencies": { + "@angular/common": "~2.2.0", + "@angular/compiler": "~2.2.0", + "@angular/core": "~2.2.0", + "@angular/forms": "~2.2.0", + "@angular/http": "~2.2.0", + "@angular/platform-browser": "~2.2.0", + "@angular/platform-browser-dynamic": "~2.2.0", + "@angular/router": "~3.2.0", + "@angular/upgrade": "~2.2.0", + "angular-in-memory-web-api": "~0.1.15", + "core-js": "^2.4.1", + "reflect-metadata": "^0.1.8", + "rxjs": "5.0.0-beta.12", + "systemjs": "0.19.39", + "zone.js": "^0.6.25" + }, + "devDependencies": { + "@types/core-js": "^0.9.34", + "typescript": "^2.0.3" + } +} +``` +Tsconfig.json +``` +{ + "compileOnSave": true, + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": false + }, + "exclude": [ + "node_modules/*" + ], + "typeRoots": [ + "node_modules/@types/" + ] +} +``` + +## Create your Angular application + +Create an `app` subfolder off the project root directory. + +Create the following files in the `app` subfolder: + +Systemjs.config.js +``` +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + // map tells the System loader where to look for things + map: { + app: '', + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); +``` + +Main.ts +``` +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app.module'; +const platform = platformBrowserDynamic(); +platform.bootstrapModule(AppModule); +``` + +App.module.ts +``` +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } +``` + +App.component.ts +``` +import { Component } from '@angular/core'; +@Component({ + selector: 'my-app', + template: '

Hello Angular!

' +}) +export class AppComponent { } +``` + +## Edit _layout.cshtml to host the Angular application + +Open `Views/shared/_layout.cshtml` file and insert Angular application’s scripts and `` tag. + +_layout.cshtml +``` + + + + + + @ViewData["Title"] - AngularWithDotnetCore + + + + + + + + + + @Html.ApplicationInsightsJavaScript(TelemetryConfiguration) + + + + + + + + + + + + + + +
+Loading… + @RenderBody() +
+
+

© 2016 - AngularWithDotnetCore

+
+
+ + + + + + + + + + + + + @RenderSection("scripts", required: false) + + +``` + +## Build and run the application. + +.NET Core MVC application works but the Angular app does not. If you open the developer's tool, and in the console tab, you will see a lot of 404 erros. + +### 404 Errors + +These 404 Errors indicate that the browser could not find a lot of files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? + +### Redirect request path to physical folder + +.NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed as such so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder in `wwwroot` folder named `app`. + +Angular app runs in browser and therefore the app and its supporting libraries (`node_modules`) must be accessible to browsers. You can simply develop the angular app inside of `wwwroot`. Your `node_modules` folder would be a sub folder of `wwwroot`. Your `package.json` file would have to stay in `wwwroot` as well. However, visual studio’s npm package manager only works in the root project folder. Therefore, you would have to manage the npm packages outside of Visual Studio 2015. + +Fortunately, you can redirect the request `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. + +``` +app.UseStaticFiles(new StaticFileOptions + { + RequestPath = new PathString("/app"), + FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "app")) + }); + app.UseStaticFiles(new StaticFileOptions + { + RequestPath = new PathString("/node_modules"), + FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")) + }); +``` +The above code asks .NET Core to redirect any request path starting with `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. + +Rebuid and run the application again, you will see "Angular Works" at every page of the MVC application. + +## Move Angular app to its own Controller and View + +## Add Angular routes + + + From a1fa841462a02ac1987579703360ee00d04cceb9 Mon Sep 17 00:00:00 2001 From: rexebin Date: Sun, 20 Nov 2016 16:13:56 +0000 Subject: [PATCH 02/23] Angular-dotnet-core: WIP --- .../ts/latest/cookbook/angular-dotnet-core.md | 73 ++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-dotnet-core.md b/public/docs/ts/latest/cookbook/angular-dotnet-core.md index 584e9fc344..1788bfd6b3 100644 --- a/public/docs/ts/latest/cookbook/angular-dotnet-core.md +++ b/public/docs/ts/latest/cookbook/angular-dotnet-core.md @@ -123,7 +123,7 @@ Systemjs.config.js // packages tells the System loader how to load when no filename and/or no extension packages: { app: { - main: './main.js', + main: './app/main.js', defaultExtension: 'js' }, rxjs: { @@ -167,7 +167,11 @@ export class AppComponent { } ## Edit _layout.cshtml to host the Angular application -Open `Views/shared/_layout.cshtml` file and insert Angular application’s scripts and `` tag. +Open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `head` section. + +In order to bootstrap the Angular app, also insert `Loading…` above `@RenderBody()` just after the navigation toolbar. + +The result should look like this: _layout.cshtml ``` @@ -177,7 +181,6 @@ _layout.cshtml @ViewData["Title"] - AngularWithDotnetCore - @@ -197,7 +200,7 @@ _layout.cshtml - + @@ -257,19 +260,22 @@ _layout.cshtml ## Build and run the application. -.NET Core MVC application works but the Angular app does not. If you open the developer's tool, and in the console tab, you will see a lot of 404 erros. +Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `_layout.cshtml` above. + ### 404 Errors -These 404 Errors indicate that the browser could not find a lot of files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? +These 404 errors indicate that the browser could not find files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? ### Redirect request path to physical folder .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed as such so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder in `wwwroot` folder named `app`. -Angular app runs in browser and therefore the app and its supporting libraries (`node_modules`) must be accessible to browsers. You can simply develop the angular app inside of `wwwroot`. Your `node_modules` folder would be a sub folder of `wwwroot`. Your `package.json` file would have to stay in `wwwroot` as well. However, visual studio’s npm package manager only works in the root project folder. Therefore, you would have to manage the npm packages outside of Visual Studio 2015. +In this case, the browser is search for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` at root into `wwwroot` folder or move/copy `node_modules` folder into `wwwroot`, because: +1. You would have to work exclusively inside `wwwroot` for angular app which is not ideal. +1. You would have to manage the npm packages outside of Visual Studio 2015. Becuase visual studio’s npm package manager only works when there is a `package.json` file in the root project folder and the package manager will install npm packages into `node_modules` at root. -Fortunately, you can redirect the request `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. +Fortunately, you can redirect the incoming request path of `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. ``` app.UseStaticFiles(new StaticFileOptions @@ -283,13 +289,60 @@ app.UseStaticFiles(new StaticFileOptions FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")) }); ``` -The above code asks .NET Core to redirect any request path starting with `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. +The above code asks .NET Core to redirect any request asking for resources in `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. -Rebuid and run the application again, you will see "Angular Works" at every page of the MVC application. +Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. ## Move Angular app to its own Controller and View +Now, you have seen that the Angular app is working. However, By boostraping it inside `_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. + +### Create Controller and View for the Angular app + +1. Create a MVC Controller called `AppController` + + * In Visual Studio, right click the `Controller` folder and select `Add` | `New Item...` + * In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. + * Enter `AppController.cs` in the name box below and click `Add` button. + + Angular app will use the `Index` action in side the generated `AppController` class, so you do not need to change anything in the `AppController` class. + +1. Create the View for the `Index` action of `AppController` + + * Create a new `App` folder under `Views` folder at root + * Right click the `App` folder and select `Add` | `New Item...` + * In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right + * Leave the default name to `Index.cshtml` and click `Add` button. + * Open `_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` + ``` + + + + ``` + * Cut and paste `Loading…` from `_layout.cshtml` to `Views/App/Index.cshtml` + + The content of `Views/App/Index.cshtml` should look like this: + ``` + + + + + Loading… + ``` +1. Add a navigation link to the top navbar + + * Open `_layout.cshtml`, add `
  • Angular App
  • ` under `
  • Contact
  • ` + +### Build and run + +Now click `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. + ## Add Angular routes + From 194ff72df2683373ffbd689379bba3ed6b85f86b Mon Sep 17 00:00:00 2001 From: rexebin Date: Sun, 20 Nov 2016 19:00:51 +0000 Subject: [PATCH 03/23] angular-dotnet-core: draft is done. --- .../ts/latest/cookbook/angular-dotnet-core.md | 170 ++++++++++++++++-- 1 file changed, 159 insertions(+), 11 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-dotnet-core.md b/public/docs/ts/latest/cookbook/angular-dotnet-core.md index 1788bfd6b3..0b6d23261a 100644 --- a/public/docs/ts/latest/cookbook/angular-dotnet-core.md +++ b/public/docs/ts/latest/cookbook/angular-dotnet-core.md @@ -3,7 +3,9 @@ This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. .NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. -In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. +In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. + +This cookbook is focused on getting Angular app to work within .NET Core application. How Angular works is out of the scope of this cookbook. Although this cookbook does not explain how and why the angular code works, it provides all the code snippet required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. # Prerequisite @@ -21,7 +23,7 @@ In this cookbook, you will create a new .NET Core Web Application project and th * Select `File` | `New` | `Project` from the menu * In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` -* Select `ASP.NET Core Web Application (.NET Core) template, give the project a name, and click OK. +* Select `ASP.NET Core Web Application (.NET Core)` template, give the project a name (this cookbook uses `AngularWithDotnetCore`), and click OK. * Select `Web Application` and click OK. Wait for visual studio to restore packages. # Create Configuration files for your Angular app. @@ -260,7 +262,7 @@ _layout.cshtml ## Build and run the application. -Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `_layout.cshtml` above. +Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. ### 404 Errors @@ -289,13 +291,18 @@ app.UseStaticFiles(new StaticFileOptions FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")) }); ``` +Remember to insert the following using statement to `startup.cs`: +``` +using Microsoft.Extensions.FileProviders; +using System.IO; +``` The above code asks .NET Core to redirect any request asking for resources in `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. ## Move Angular app to its own Controller and View -Now, you have seen that the Angular app is working. However, By boostraping it inside `_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. +Now, you have seen that the Angular app is working. However, By boostraping it inside `Views/Shared/_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. ### Create Controller and View for the Angular app @@ -313,7 +320,7 @@ Now, you have seen that the Angular app is working. However, By boostraping it i * Right click the `App` folder and select `Add` | `New Item...` * In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right * Leave the default name to `Index.cshtml` and click `Add` button. - * Open `_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` + * Open `Views/Shared/_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` ``` @@ -321,7 +328,7 @@ Now, you have seen that the Angular app is working. However, By boostraping it i System.import('app').catch(function(err){ console.error(err); }); ``` - * Cut and paste `Loading…` from `_layout.cshtml` to `Views/App/Index.cshtml` + * Cut and paste `Loading…` from `Views/Shared/_layout.cshtml` to `Views/App/Index.cshtml` The content of `Views/App/Index.cshtml` should look like this: ``` @@ -330,18 +337,159 @@ Now, you have seen that the Angular app is working. However, By boostraping it i - - Loading… +
    + Loading… +
    ``` 1. Add a navigation link to the top navbar - * Open `_layout.cshtml`, add `
  • Angular App
  • ` under `
  • Contact
  • ` + * Open `Views/Shared/_layout.cshtml`, under `
  • Contact
  • `, add: + ``` +
  • Angular App
  • + ``` ### Build and run -Now click `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. +Now click `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. + +If the Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via router. In the following sections, you will replace the above basic angular app with the sample application used in `Router & Navigation` charpter and make it work inside .NET Core environment. + +## The Sample application + +### Download and copy the sample application + +1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of `Router & Navigation`. Feel free to explore the application before click the `Download your plunk as a ZIP file` at the right up corner. + +1. Unzip the downloaded zip file to a folder and do the following: + * Open the extracted folder from your downloaded zip file, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. + * In Visual Studio, right click the `app` folder at the root, select `Open folder in File Explorer` to open your app folder, paste the above copied files, when promoted, select `Replace the files in the destination`. + * Follow the above two steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your project. + + Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. + +### Add styles + +To style your Angular app the same way as the sample application, open `Views/Shared/_layout.cshtml` and insert `` next to `` tag in the `<head>` section. + +### Set base href + +Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. + +If you build and run the application and go to `Angular App`, you will that your angular app is broken and there is an error in the consle: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + +To fix the above error, open `/app/Systemjs.config.js` file, find ` main: './app/main.js',` and change it to `./main.js`. + +Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstraped but it is stopped due to errors. In the `Console` tab of the browser's `Developer tools`, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. + +### .NET Core's Pascal Case url + +.NET Core parse urls to Pascale case by default. As you have seen, it does not work well with JavaScript frameworks like Angular. + +Fortunately, you can configure .NET Core to use lower case to parse its urls. + +Open `startup.cs` file, in `ConfigureServices` method, insert the followling line before `service.AddMvc()`: +``` +services.Configure<RouteOptions>(options => options.LowercaseUrls = true); +``` + +Remember to insert `using Microsoft.AspNetCore.Routing;` to `startup.cs` file. + +Now rebuild and run your application, the above error goes away. However only `Heros` and `Admin` link work. The lazy load module `Crisis Center` is broken. In the Console, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. + +### Fix Lazy-Loading Modules + +The problem is that Angular could not find the lazy-loading modules. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: +``` +... + { + path: 'admin', + loadChildren: 'app/admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, +... + { + path: 'crisis-center', + loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule', + data: { + preload: true + } + } +``` + +The above code shows that you have two lazy load modules: `crisis-center` and `admin`, both are loaded using absolute path because their `loadChildren` start with `app/`. Why is Angular requesting `crisis-center.module` in ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because your base href is `/app/`. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path. + +However, in the .NET Core environment, it works in a completely different way. It does not take base href into consideration. + +To fix the issue, simple use relative path like this: + +``` +... + { + path: 'admin', + loadChildren: './admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, +... + { + path: 'crisis-center', + loadChildren: './crisis-center/crisis-center.module#CrisisCenterModule', + data: { + preload: true + } + } +``` + +Now, build and run, you will see that the Angular app is runing without errors until you refresh the browser. + +## Configure .NET Core routes for Angular app + +The Angular app has deep links, such as `/app/heros` and `/app/heros/11`. When you navigate inside the Angular app, it does not send any request to the .NET Core server. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. + +When .NET Core a request url, it tries to match its routes configration. The current route setting is as follow in the `startup.cs` file: +``` + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); +``` + +In this case, when .NET Core sees `/app/heros` url, it will try to excute `AppController`'s `Heros` action, which does not exist. + +In order to solve this problem, you can create a new route map and redirect all url starting with `/app` to `/app`. Change the routes to this: + +``` + app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + + routes.MapRoute( + name: "angular", + template: "app/{*routes}", + defaults: new { controller = "App", action = "Index" } + ); + }); +``` + +Notice the second `MapRoute`, it will ask .NET Core to excute `AppController`'s `Index` action for all urls starting with `app/`. + +If you build and run the application and go to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. + +# Summary + +Angular application can live inside of a larger .NET Core web application. This cookbook solved the challenges: + +1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request path to physical path in the root folder. It enables visual studio to manage npm packages for your. It also allow you to use any folder inside the project for your Angular app. + +1. .NET Core uses Pascal case to parse urls, which does not play well with Angular. You can configure .NET Core to parse lower case urls. + +1. Angular router uses `base href` but .NET Core ignores it. Angular app has to use relative path for its lazy-loading modules. -## Add Angular routes +1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. + From eed76998503281e702f24db4c443f284557e84b9 Mon Sep 17 00:00:00 2001 From: rexebin <rexebin@gmail.com> Date: Sun, 20 Nov 2016 19:04:04 +0000 Subject: [PATCH 04/23] minor title adjustment. --- .../ts/latest/cookbook/angular-dotnet-core.md | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-dotnet-core.md b/public/docs/ts/latest/cookbook/angular-dotnet-core.md index 0b6d23261a..25ec26a26f 100644 --- a/public/docs/ts/latest/cookbook/angular-dotnet-core.md +++ b/public/docs/ts/latest/cookbook/angular-dotnet-core.md @@ -1,5 +1,3 @@ -# Cookbook Introduction - This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. .NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. @@ -26,7 +24,9 @@ This cookbook is focused on getting Angular app to work within .NET Core applica * Select `ASP.NET Core Web Application (.NET Core)` template, give the project a name (this cookbook uses `AngularWithDotnetCore`), and click OK. * Select `Web Application` and click OK. Wait for visual studio to restore packages. -# Create Configuration files for your Angular app. +# Create your Angular app + +## Create Configuration files for your Angular app. In the root folder, create `package.json` and `tsconfig.json` files. Populate them by pasting the contents below. @@ -300,11 +300,11 @@ The above code asks .NET Core to redirect any request asking for resources in `/ Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. -## Move Angular app to its own Controller and View +# Move Angular app to its own Controller and View Now, you have seen that the Angular app is working. However, By boostraping it inside `Views/Shared/_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. -### Create Controller and View for the Angular app +## Create Controller and View for the Angular app 1. Create a MVC Controller called `AppController` @@ -348,15 +348,15 @@ Now, you have seen that the Angular app is working. However, By boostraping it i <li><a asp-area="" asp-controller="App" asp-action="Index">Angular App</a></li> ``` -### Build and run +## Build and run Now click `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. If the Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via router. In the following sections, you will replace the above basic angular app with the sample application used in `Router & Navigation` charpter and make it work inside .NET Core environment. -## The Sample application +# The Sample application -### Download and copy the sample application +## Download and copy the sample application 1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of `Router & Navigation`. Feel free to explore the application before click the `Download your plunk as a ZIP file` at the right up corner. @@ -367,11 +367,11 @@ If the Angular app has only one page, this would be the end of this cookbook. Ho Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. -### Add styles +## Add styles To style your Angular app the same way as the sample application, open `Views/Shared/_layout.cshtml` and insert `<link href="~/css/styles.css" rel="stylesheet" />` next to `<title>` tag in the `<head>` section. -### Set base href +## Set base href Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. @@ -381,7 +381,7 @@ To fix the above error, open `/app/Systemjs.config.js` file, find ` main: './app Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstraped but it is stopped due to errors. In the `Console` tab of the browser's `Developer tools`, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. -### .NET Core's Pascal Case url +## .NET Core's Pascal Case url .NET Core parse urls to Pascale case by default. As you have seen, it does not work well with JavaScript frameworks like Angular. @@ -396,7 +396,7 @@ Remember to insert `using Microsoft.AspNetCore.Routing;` to `startup.cs` file. Now rebuild and run your application, the above error goes away. However only `Heros` and `Admin` link work. The lazy load module `Crisis Center` is broken. In the Console, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. -### Fix Lazy-Loading Modules +## Fix Lazy-Loading Modules The problem is that Angular could not find the lazy-loading modules. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: ``` @@ -441,7 +441,7 @@ To fix the issue, simple use relative path like this: Now, build and run, you will see that the Angular app is runing without errors until you refresh the browser. -## Configure .NET Core routes for Angular app +# Configure .NET Core routes for Angular app The Angular app has deep links, such as `/app/heros` and `/app/heros/11`. When you navigate inside the Angular app, it does not send any request to the .NET Core server. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. @@ -489,8 +489,3 @@ Angular application can live inside of a larger .NET Core web application. This 1. Angular router uses `base href` but .NET Core ignores it. Angular app has to use relative path for its lazy-loading modules. 1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. - - - - - From ce0af2ac48fa7e8762d2a61fd17645a0260a0b5b Mon Sep 17 00:00:00 2001 From: rexebin <rexebin@gmail.com> Date: Sun, 20 Nov 2016 22:26:42 +0000 Subject: [PATCH 05/23] move code to _example --- .../angular-in-dotnet-core/ts/_layout.html | 82 +++ .../ts/app/app-routing.module.ts | 74 +++ .../ts/app/app.component.ts | 7 + .../ts/app/app.module.ts | 10 + .../angular-in-dotnet-core/ts/app/main.ts | 5 + .../angular-in-dotnet-core/ts/index.html | 8 + .../angular-in-dotnet-core/ts/nav.html | 2 + .../angular-in-dotnet-core/ts/startup.ts | 49 ++ .../angular-in-dotnet-core/ts/styles.html | 2 + .../ts/latest/cookbook/angular-dotnet-core.md | 491 ------------------ .../cookbook/angular-in-dotnet-core.jade | 267 ++++++++++ 11 files changed, 506 insertions(+), 491 deletions(-) create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/_layout.html create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/index.html create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/nav.html create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/startup.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/styles.html delete mode 100644 public/docs/ts/latest/cookbook/angular-dotnet-core.md create mode 100644 public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html b/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html new file mode 100644 index 0000000000..a4d6ebab63 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html @@ -0,0 +1,82 @@ +<!-- #docregion --> +<!DOCTYPE html> + <html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>@ViewData["Title"] - AngularWithDotnetCore + + + + + + + + + @Html.ApplicationInsightsJavaScript(TelemetryConfiguration) + + + + + + + + + + + + + + +
    + Loading… + @RenderBody() +
    +
    +

    © 2016 - AngularWithDotnetCore

    +
    +
    + + + + + + + + + + + + + @RenderSection("scripts", required: false) + + \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts new file mode 100644 index 0000000000..6ba3ba0cad --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts @@ -0,0 +1,74 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CanDeactivateGuard } from './can-deactivate-guard.service'; +import { AuthGuard } from './auth-guard.service'; +import { PreloadSelectedModules } from './selective-preload-strategy'; + +// #docregion absolute +const appRoutes: Routes = [ + { + path: 'admin', + loadChildren: 'app/admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, + { + path: '', + redirectTo: '/heroes', + pathMatch: 'full' + }, + { + path: 'crisis-center', + loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule', + data: { + preload: true + } + } +]; +// #enddocregion absolute + +// #docregion relative +const appRoutes: Routes = [ + { + path: 'admin', + loadChildren: './admin/admin.module#AdminModule', + canLoad: [AuthGuard] + }, + { + path: '', + redirectTo: '/heroes', + pathMatch: 'full' + }, + { + path: 'crisis-center', + loadChildren: './crisis-center/crisis-center.module#CrisisCenterModule', + data: { + preload: true + } + } +]; +// #enddocregion relative + +@NgModule({ + imports: [ + RouterModule.forRoot( + appRoutes, + { preloadingStrategy: PreloadSelectedModules } + ) + ], + exports: [ + RouterModule + ], + providers: [ + CanDeactivateGuard, + PreloadSelectedModules + ] +}) +export class AppRoutingModule {} + + +/* +Copyright 2016 Google Inc. All Rights Reserved. +Use of this source code is governed by an MIT-style license that +can be found in the LICENSE file at http://angular.io/license +*/ \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts new file mode 100644 index 0000000000..966139d7e7 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts @@ -0,0 +1,7 @@ +// #docregion +import { Component } from '@angular/core'; +@Component({ + selector: 'my-app', + template: '

    Hello Angular!

    ' +}) +export class AppComponent { } \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts new file mode 100644 index 0000000000..ba15af61a9 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts @@ -0,0 +1,10 @@ +// #docregion +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +@NgModule({ + imports: [ BrowserModule ], + declarations: [ AppComponent ], + bootstrap: [ AppComponent ] +}) +export class AppModule { } \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts new file mode 100644 index 0000000000..b4b8cec553 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts @@ -0,0 +1,5 @@ +// #docregion +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { AppModule } from './app.module'; +const platform = platformBrowserDynamic(); +platform.bootstrapModule(AppModule); \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/index.html b/public/docs/_examples/angular-in-dotnet-core/ts/index.html new file mode 100644 index 0000000000..9e12ef7a9d --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/index.html @@ -0,0 +1,8 @@ + + + +
    + Loading… +
    \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/nav.html b/public/docs/_examples/angular-in-dotnet-core/ts/nav.html new file mode 100644 index 0000000000..ff7afca825 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/nav.html @@ -0,0 +1,2 @@ + +
  • Angular App
  • \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/startup.ts b/public/docs/_examples/angular-in-dotnet-core/ts/startup.ts new file mode 100644 index 0000000000..a6d2815723 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/startup.ts @@ -0,0 +1,49 @@ +// #docregion redirect +app.UseStaticFiles(new StaticFileOptions + { + RequestPath = new PathString("/app"), + FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "app")) + }); + app.UseStaticFiles(new StaticFileOptions + { + RequestPath = new PathString("/node_modules"), + FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")) + }); +// #enddocregion redirect + +// #docregion redirect-using +using Microsoft.Extensions.FileProviders; +using System.IO; + +// #enddocregion redirect-using + +// #docregion lowercaseurls +services.Configure(options => options.LowercaseUrls = true); +// #enddocregion lowercaseurls + +// #docregion lowercaseurls-using +using Microsoft.AspNetCore.Routing +// #enddocregion lowercaseurls-using + +// #docregion route-default +app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + }); +// #enddocregion route-default + +// #docregion route-new +app.UseMvc(routes => + { + routes.MapRoute( + name: "default", + template: "{controller=Home}/{action=Index}/{id?}"); + routes.MapRoute( + name: "angular", + template: "app/{*routes}", + defaults: new { controller = "App", action = "Index" } + ); + }); +// #enddocregion route-new \ No newline at end of file diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/styles.html b/public/docs/_examples/angular-in-dotnet-core/ts/styles.html new file mode 100644 index 0000000000..5c8414927c --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/styles.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/public/docs/ts/latest/cookbook/angular-dotnet-core.md b/public/docs/ts/latest/cookbook/angular-dotnet-core.md deleted file mode 100644 index 25ec26a26f..0000000000 --- a/public/docs/ts/latest/cookbook/angular-dotnet-core.md +++ /dev/null @@ -1,491 +0,0 @@ -This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. -.NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. - -In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. - -This cookbook is focused on getting Angular app to work within .NET Core application. How Angular works is out of the scope of this cookbook. Although this cookbook does not explain how and why the angular code works, it provides all the code snippet required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. - -# Prerequisite - -1. Install Visual studio 2015 Update 3 - -1. Install .NET Core Tools for visual studio 2015 - -1. Install .Net Core SDK - -1. Install Typescript 2 for visual studio 2015 - -1. Install Node.js Tools for visual studio 2015 (optional) - -# Create a new .NET Core Web Application - -* Select `File` | `New` | `Project` from the menu -* In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` -* Select `ASP.NET Core Web Application (.NET Core)` template, give the project a name (this cookbook uses `AngularWithDotnetCore`), and click OK. -* Select `Web Application` and click OK. Wait for visual studio to restore packages. - -# Create your Angular app - -## Create Configuration files for your Angular app. - -In the root folder, create `package.json` and `tsconfig.json` files. Populate them by pasting the contents below. - -Package.json -``` -{ - "name": "angular-dotnet-core", - "version": "1.0.0", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/angular/angular.io/blob/master/LICENSE" - } - ], - "dependencies": { - "@angular/common": "~2.2.0", - "@angular/compiler": "~2.2.0", - "@angular/core": "~2.2.0", - "@angular/forms": "~2.2.0", - "@angular/http": "~2.2.0", - "@angular/platform-browser": "~2.2.0", - "@angular/platform-browser-dynamic": "~2.2.0", - "@angular/router": "~3.2.0", - "@angular/upgrade": "~2.2.0", - "angular-in-memory-web-api": "~0.1.15", - "core-js": "^2.4.1", - "reflect-metadata": "^0.1.8", - "rxjs": "5.0.0-beta.12", - "systemjs": "0.19.39", - "zone.js": "^0.6.25" - }, - "devDependencies": { - "@types/core-js": "^0.9.34", - "typescript": "^2.0.3" - } -} -``` -Tsconfig.json -``` -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es5", - "module": "commonjs", - "moduleResolution": "node", - "sourceMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "removeComments": false, - "noImplicitAny": false - }, - "exclude": [ - "node_modules/*" - ], - "typeRoots": [ - "node_modules/@types/" - ] -} -``` - -## Create your Angular application - -Create an `app` subfolder off the project root directory. - -Create the following files in the `app` subfolder: - -Systemjs.config.js -``` -/** - * System configuration for Angular samples - * Adjust as necessary for your application needs. - */ -(function (global) { - System.config({ - paths: { - // paths serve as alias - 'npm:': '/node_modules/' - }, - // map tells the System loader where to look for things - map: { - app: '', - // angular bundles - '@angular/core': 'npm:@angular/core/bundles/core.umd.js', - '@angular/common': 'npm:@angular/common/bundles/common.umd.js', - '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', - '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', - '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', - '@angular/http': 'npm:@angular/http/bundles/http.umd.js', - '@angular/router': 'npm:@angular/router/bundles/router.umd.js', - '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', - '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', - // other libraries - 'rxjs': 'npm:rxjs', - 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' - }, - // packages tells the System loader how to load when no filename and/or no extension - packages: { - app: { - main: './app/main.js', - defaultExtension: 'js' - }, - rxjs: { - defaultExtension: 'js' - } - } - }); -})(this); -``` - -Main.ts -``` -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { AppModule } from './app.module'; -const platform = platformBrowserDynamic(); -platform.bootstrapModule(AppModule); -``` - -App.module.ts -``` -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { AppComponent } from './app.component'; -@NgModule({ - imports: [ BrowserModule ], - declarations: [ AppComponent ], - bootstrap: [ AppComponent ] -}) -export class AppModule { } -``` - -App.component.ts -``` -import { Component } from '@angular/core'; -@Component({ - selector: 'my-app', - template: '

    Hello Angular!

    ' -}) -export class AppComponent { } -``` - -## Edit _layout.cshtml to host the Angular application - -Open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `head` section. - -In order to bootstrap the Angular app, also insert `Loading…` above `@RenderBody()` just after the navigation toolbar. - -The result should look like this: - -_layout.cshtml -``` - - - - - - @ViewData["Title"] - AngularWithDotnetCore - - - - - - - - - @Html.ApplicationInsightsJavaScript(TelemetryConfiguration) - - - - - - - - - - - - - - -
    -Loading… - @RenderBody() -
    -
    -

    © 2016 - AngularWithDotnetCore

    -
    -
    - - - - - - - - - - - - - @RenderSection("scripts", required: false) - - -``` - -## Build and run the application. - -Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. - - -### 404 Errors - -These 404 errors indicate that the browser could not find files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? - -### Redirect request path to physical folder - -.NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed as such so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder in `wwwroot` folder named `app`. - -In this case, the browser is search for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` at root into `wwwroot` folder or move/copy `node_modules` folder into `wwwroot`, because: -1. You would have to work exclusively inside `wwwroot` for angular app which is not ideal. -1. You would have to manage the npm packages outside of Visual Studio 2015. Becuase visual studio’s npm package manager only works when there is a `package.json` file in the root project folder and the package manager will install npm packages into `node_modules` at root. - -Fortunately, you can redirect the incoming request path of `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. - -``` -app.UseStaticFiles(new StaticFileOptions - { - RequestPath = new PathString("/app"), - FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "app")) - }); - app.UseStaticFiles(new StaticFileOptions - { - RequestPath = new PathString("/node_modules"), - FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "node_modules")) - }); -``` -Remember to insert the following using statement to `startup.cs`: -``` -using Microsoft.Extensions.FileProviders; -using System.IO; -``` -The above code asks .NET Core to redirect any request asking for resources in `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. - -Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. - -# Move Angular app to its own Controller and View - -Now, you have seen that the Angular app is working. However, By boostraping it inside `Views/Shared/_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. - -## Create Controller and View for the Angular app - -1. Create a MVC Controller called `AppController` - - * In Visual Studio, right click the `Controller` folder and select `Add` | `New Item...` - * In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. - * Enter `AppController.cs` in the name box below and click `Add` button. - - Angular app will use the `Index` action in side the generated `AppController` class, so you do not need to change anything in the `AppController` class. - -1. Create the View for the `Index` action of `AppController` - - * Create a new `App` folder under `Views` folder at root - * Right click the `App` folder and select `Add` | `New Item...` - * In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right - * Leave the default name to `Index.cshtml` and click `Add` button. - * Open `Views/Shared/_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` - ``` - - - - ``` - * Cut and paste `Loading…` from `Views/Shared/_layout.cshtml` to `Views/App/Index.cshtml` - - The content of `Views/App/Index.cshtml` should look like this: - ``` - - - -
    - Loading… -
    - ``` -1. Add a navigation link to the top navbar - - * Open `Views/Shared/_layout.cshtml`, under `
  • Contact
  • `, add: - ``` -
  • Angular App
  • - ``` - -## Build and run - -Now click `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. - -If the Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via router. In the following sections, you will replace the above basic angular app with the sample application used in `Router & Navigation` charpter and make it work inside .NET Core environment. - -# The Sample application - -## Download and copy the sample application - -1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of `Router & Navigation`. Feel free to explore the application before click the `Download your plunk as a ZIP file` at the right up corner. - -1. Unzip the downloaded zip file to a folder and do the following: - * Open the extracted folder from your downloaded zip file, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. - * In Visual Studio, right click the `app` folder at the root, select `Open folder in File Explorer` to open your app folder, paste the above copied files, when promoted, select `Replace the files in the destination`. - * Follow the above two steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your project. - - Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. - -## Add styles - -To style your Angular app the same way as the sample application, open `Views/Shared/_layout.cshtml` and insert `` next to `` tag in the `<head>` section. - -## Set base href - -Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - -If you build and run the application and go to `Angular App`, you will that your angular app is broken and there is an error in the consle: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. - -To fix the above error, open `/app/Systemjs.config.js` file, find ` main: './app/main.js',` and change it to `./main.js`. - -Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstraped but it is stopped due to errors. In the `Console` tab of the browser's `Developer tools`, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. - -## .NET Core's Pascal Case url - -.NET Core parse urls to Pascale case by default. As you have seen, it does not work well with JavaScript frameworks like Angular. - -Fortunately, you can configure .NET Core to use lower case to parse its urls. - -Open `startup.cs` file, in `ConfigureServices` method, insert the followling line before `service.AddMvc()`: -``` -services.Configure<RouteOptions>(options => options.LowercaseUrls = true); -``` - -Remember to insert `using Microsoft.AspNetCore.Routing;` to `startup.cs` file. - -Now rebuild and run your application, the above error goes away. However only `Heros` and `Admin` link work. The lazy load module `Crisis Center` is broken. In the Console, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. - -## Fix Lazy-Loading Modules - -The problem is that Angular could not find the lazy-loading modules. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: -``` -... - { - path: 'admin', - loadChildren: 'app/admin/admin.module#AdminModule', - canLoad: [AuthGuard] - }, -... - { - path: 'crisis-center', - loadChildren: 'app/crisis-center/crisis-center.module#CrisisCenterModule', - data: { - preload: true - } - } -``` - -The above code shows that you have two lazy load modules: `crisis-center` and `admin`, both are loaded using absolute path because their `loadChildren` start with `app/`. Why is Angular requesting `crisis-center.module` in ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because your base href is `/app/`. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path. - -However, in the .NET Core environment, it works in a completely different way. It does not take base href into consideration. - -To fix the issue, simple use relative path like this: - -``` -... - { - path: 'admin', - loadChildren: './admin/admin.module#AdminModule', - canLoad: [AuthGuard] - }, -... - { - path: 'crisis-center', - loadChildren: './crisis-center/crisis-center.module#CrisisCenterModule', - data: { - preload: true - } - } -``` - -Now, build and run, you will see that the Angular app is runing without errors until you refresh the browser. - -# Configure .NET Core routes for Angular app - -The Angular app has deep links, such as `/app/heros` and `/app/heros/11`. When you navigate inside the Angular app, it does not send any request to the .NET Core server. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. - -When .NET Core a request url, it tries to match its routes configration. The current route setting is as follow in the `startup.cs` file: -``` - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - }); -``` - -In this case, when .NET Core sees `/app/heros` url, it will try to excute `AppController`'s `Heros` action, which does not exist. - -In order to solve this problem, you can create a new route map and redirect all url starting with `/app` to `/app`. Change the routes to this: - -``` - app.UseMvc(routes => - { - routes.MapRoute( - name: "default", - template: "{controller=Home}/{action=Index}/{id?}"); - - routes.MapRoute( - name: "angular", - template: "app/{*routes}", - defaults: new { controller = "App", action = "Index" } - ); - }); -``` - -Notice the second `MapRoute`, it will ask .NET Core to excute `AppController`'s `Index` action for all urls starting with `app/`. - -If you build and run the application and go to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. - -# Summary - -Angular application can live inside of a larger .NET Core web application. This cookbook solved the challenges: - -1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request path to physical path in the root folder. It enables visual studio to manage npm packages for your. It also allow you to use any folder inside the project for your Angular app. - -1. .NET Core uses Pascal case to parse urls, which does not play well with Angular. You can configure .NET Core to parse lower case urls. - -1. Angular router uses `base href` but .NET Core ignores it. Angular app has to use relative path for its lazy-loading modules. - -1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade new file mode 100644 index 0000000000..5e089e41bd --- /dev/null +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -0,0 +1,267 @@ +include ../_util-fns + +:marked + This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. + .NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. + + In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. + + This cookbook is focused on getting Angular app to work within .NET Core application. How Angular works is out of the scope of this cookbook. Although this cookbook does not explain how and why the angular code works, it provides all the code snippet required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. + +a#toc +:marked + ## Table of contents + * [Prerequisite](#prerequisite) + * [Create a new .NET Core Web Application](#create-dotnet-core-application) + * [Create your Angular app](#create-angular-app) + * [Move Angular app to its own MVC Controller](#move-app) + * [Angular app with routes](#angular-app-with-routes) + * [Summary](#summary) + +a#prerequisite +.l-main-section +:marked + ## Prerequisite + 1. Install Visual studio 2015 Update 3 + 1. Install .NET Core Tools for visual studio 2015 + 1. Install .Net Core SDK + 1. Install Typescript 2 for visual studio 2015 + 1. Install Node.js Tools for visual studio 2015 (optional) + +a#create-dotnet-core-application +.l-main-section +:marked + ## Create a new .NET Core Web Application + + 1. Select `File` | `New` | `Project` from the menu + 1. In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` + 1. Select `ASP.NET Core Web Application (.NET Core)` template, give the project a name (this cookbook uses `AngularWithDotnetCore`), and click OK. + 1. Select `Web Application` and click OK. Wait for visual studio to restore packages. + +a#create-angular-app +.l-main-section +:marked + ## Create your Angular app + + ### Create Configuration files for your Angular app. + + In the root folder, create `package.json` and `tsconfig.json` files. Populate them by pasting the contents below. + ++makeTabs( + `angular-in-dotnet-core/ts/package.json, + angular-in-dotnet-core/ts/tsconfig.json`, + null, + `package.json, + tsconfig.json` +)(format='.') + +:marked + ### Create your Angular app + + Create an `app` subfolder off the project root directory. + + Create the following files in the `app` subfolder: + ++makeTabs( + `angular-in-dotnet-core/ts/app/systemjs.config.js, + angular-in-dotnet-core/ts/app/app.module.ts, + angular-in-dotnet-core/ts/app/app.component.ts, + angular-in-dotnet-core/ts/app/main.ts`, + null, + `app/systemjs.config.js, + app/app.module.ts, + app/app.component.ts, + app/main.ts` +)(format='.') + +:marked + ### Edit `Views/shared/_layout.cshtml` to host the Angular application + + Open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `head` section. + + In order to bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()` just after the navigation toolbar. + + The result should look like this: + ++makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') + +:marked + Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. + + #### 404 Errors + + These 404 errors indicate that the browser could not find files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? + + #### Redirect request path to physical folder + + .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed as such so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder in `wwwroot` folder named `app`. + + In this case, the browser is search for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` at root into `wwwroot` folder or move/copy `node_modules` folder into `wwwroot`, because: + 1. You would have to work exclusively inside `wwwroot` for angular app which is not ideal. + 1. You would have to manage the npm packages outside of Visual Studio 2015. Becuase visual studio’s npm package manager only works when there is a `package.json` file in the root project folder and the package manager will install npm packages into `node_modules` at root. + + Fortunately, you can redirect the incoming request path of `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. + ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect', 'startup.cs')(format='.') + +:marked + Remember to insert the following using statement to `startup.cs`: + ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect-using', 'startup.cs')(format='.') + +:marked + The above code asks .NET Core to redirect any request asking for resources in `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. + + Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. + +a#move-app +.l-main-section +:marked + ## Move Angular app to its own Controller and View + + Now, you have seen that the Angular app is working. However, By boostraping it inside `Views/Shared/_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. + + ### Create Controller and View for the Angular app + + 1. Create a MVC Controller called `AppController` + + 1. In Visual Studio, right click the `Controller` folder and select `Add` | `New Item...` + 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. + 1. Enter `AppController.cs` in the name box below and click `Add` button. + + Angular app will use the `Index` action in side the generated `AppController` class, so you do not need to change anything in the `AppController` class. + + 1. Create the View for the `Index` action of `AppController` + + 1. Create a new `App` folder under `Views` folder at root + 1. Right click the `App` folder and select `Add` | `New Item...` + 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right + 1. Leave the default name to `Index.cshtml` and click `Add` button. + 1. Open `Views/Shared/_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` + ``` + <!-- 2. Configure SystemJS --> + <script src="~/app/systemjs.config.js"></script> + <script> + System.import('app').catch(function(err){ console.error(err); }); + </script> + ``` + 1. Cut and paste `<my-app>Loading…</my-app>` from `Views/Shared/_layout.cshtml` to `Views/App/Index.cshtml`. Wrap it in a `<div>` with minimum height of 300px. + + The content of `Views/App/Index.cshtml` should look like this: + ++makeExample('angular-in-dotnet-core/ts/index.html', null, 'Views/App/Index.cshtml')(format='.') +:marked + ### Add a navigation link to the top navbar + + Open `Views/Shared/_layout.cshtml`, under `<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>`, add: + ++makeExample('angular-in-dotnet-core/ts/nav.html', null, 'Views/Shared/_layout.cshtml')(format='.') + +:marked + ### Build and run + + Press `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. + + If the Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via Angular router. + + In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) charpter and make it work inside .NET Core environment. + +a#angular-app-with-routes +.l-main-section +:marked + ## Angular app with routes + + ### Download and copy the sample application + + 1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of [Router & Navigation](../guide/router.html). Feel free to explore the app in Plunk before clicking the `Download your plunk as a ZIP file` button at the top right corner. + + 1. Unzip the downloaded zip file to a folder and do the following: + * Open the extracted folder from your downloaded zip file, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. + * In Visual Studio, right click the `app` folder at the root, select `Open folder in File Explorer` to open your app folder, paste the above copied files, when promoted, select `Replace the files in the destination`. + + 1. Repeat the above steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your project. + + Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. + + ### Add Styles + + To style your Angular app the same way as the sample application, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to `<title>` tag in the `<head>` section: + ++makeExample('angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') + +:marked + ### Set base href + + Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. + + If you build and run the application and go to `Angular App`, you will that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + + To fix the above error, open `/app/Systemjs.config.js` file, find ` main: './app/main.js'` and change it to `./main.js`. + + Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstraped but it is stopped due to errors. In the `Console` tab of the browser's `Developer tools`, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. + + ### .NET Core's Pascal Case Urls + + .NET Core parse urls to Pascale case by default. As you have seen, it does not work well with JavaScript frameworks like Angular. + + Fortunately, you can configure .NET Core to use lower case to parse its urls. + + Open `startup.cs` file, in `ConfigureServices` method, insert the followling line before `service.AddMvc()`: + ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls', 'startup.cs')(format='.') +:marked + Remember to insert the following `using` statement to `startup.cs`: + ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') +:marked + Now rebuild and run your application, the above error goes away. However only `Heros` and `login` links work as intended. The lazy load module `Crisis Center` and `Admin` are broken. In the Console, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. + + ### Fix Lazy Loaded Modules + + The problem is that Angular could not find the lazy loaded modules. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: + ++makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') +:marked + The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you set the base href to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path because of the base href. + + However, in the .NET Core environment, it works in a completely different way. It does not take base href into consideration. + + To fix the issue, simple use relative path like this: + ++makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') +:marked + Now, build and run, you will see that the Angular app is runing without errors until you refresh the browser. + + ## Configure .NET Core routes for Angular app + + The Angular app has deep links, such as `/app/heros` and `/app/heros/11`. When you navigate inside the Angular app, it does not send any request to the .NET Core server. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. + + When .NET Core a request url, it tries to match its routes configration. The current route setting is as follow in the `startup.cs` file: + ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') + +:marked + In this case, when .NET Core sees `/app/heros` url, it will try to excute `AppController`'s `Heros` action, which does not exist. + + In order to solve this problem, you can create a new route map and redirect all url starting with `/app` to `/app`. Change the routes to this: ++makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-new', 'startup.cs')(format='.') + +:marked + Notice the second `MapRoute`, it will ask .NET Core to excute `AppController`'s `Index` action for all urls starting with `app/`. + + If you build and run the application and navigate to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. + +a#summary +.l-main-section +:marked + ## Summary + + Angular application can live inside of a larger .NET Core web application. There are a few challenges: + + 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request path to physical path in the root folder. It enables visual studio to manage npm packages for your. It also allow you to use any folder inside the project for your Angular app. + + 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular. You can configure .NET Core to parse lower case urls. + + 1. Angular router uses `base href` but .NET Core ignores it. Angular app has to use relative path for its lazy loaded modules. + + 1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. From 01fa33c52d64189163d8fb21b525fd141b588965 Mon Sep 17 00:00:00 2001 From: rexebin <rexebin@gmail.com> Date: Sun, 20 Nov 2016 22:38:30 +0000 Subject: [PATCH 06/23] update cookbook. --- .../latest/cookbook/angular-in-dotnet-core.jade | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 5e089e41bd..97755b009c 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -4,9 +4,7 @@ include ../_util-fns This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. .NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. - In this cookbook, you will create a new .NET Core Web Application project and then create an Angular app from scratch, using only visual studio 2015. - - This cookbook is focused on getting Angular app to work within .NET Core application. How Angular works is out of the scope of this cookbook. Although this cookbook does not explain how and why the angular code works, it provides all the code snippet required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. + This cookbook is focused on getting Angular app to work within .NET Core application. It does not explain how and why the angular code works. However this cookbook will provides all the code snippets required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. a#toc :marked @@ -22,11 +20,11 @@ a#prerequisite .l-main-section :marked ## Prerequisite - 1. Install Visual studio 2015 Update 3 - 1. Install .NET Core Tools for visual studio 2015 - 1. Install .Net Core SDK - 1. Install Typescript 2 for visual studio 2015 - 1. Install Node.js Tools for visual studio 2015 (optional) + 1. Download and install [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) + 1. Download and install [.NET Core Tools for visual studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) + 1. Download and Install [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) + 1. Download and install [Typescript 2 for visual studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) + 1. Download and install [Node.js Tools for visual studio 2015](https://aka.ms/getntvs) (optional) a#create-dotnet-core-application .l-main-section @@ -79,7 +77,7 @@ a#create-angular-app Open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `head` section. - In order to bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()` just after the navigation toolbar. + To bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()` just after the navigation toolbar. The result should look like this: From b85b2e2d5070d07aed27ba6e7d57e8f308afcd35 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 13:20:58 +0000 Subject: [PATCH 07/23] review draft. --- .../ts/app/systemjs.config.ts | 42 ++++ .../angular-in-dotnet-core/ts/lib.html | 12 ++ .../angular-in-dotnet-core/ts/package1.json | 35 ++++ .../angular-in-dotnet-core/ts/tsconfig1.json | 19 ++ .../cookbook/angular-in-dotnet-core.jade | 179 ++++++++++-------- 5 files changed, 210 insertions(+), 77 deletions(-) create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/lib.html create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/package1.json create mode 100644 public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts new file mode 100644 index 0000000000..6d195ae911 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts @@ -0,0 +1,42 @@ +// #docregion +/** + * System configuration for Angular samples + * Adjust as necessary for your application needs. + */ +(function (global) { + System.config({ + paths: { + // paths serve as alias + 'npm:': '/node_modules/' + }, + // map tells the System loader where to look for things + map: { + // our app is within the app folder + // base href is set to "app" for routing which does the same thing "app:'app'" below, therefore we have to remove the "app" here. + app: '', + // angular bundles + '@angular/core': 'npm:@angular/core/bundles/core.umd.js', + '@angular/common': 'npm:@angular/common/bundles/common.umd.js', + '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', + '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', + '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', + '@angular/http': 'npm:@angular/http/bundles/http.umd.js', + '@angular/router': 'npm:@angular/router/bundles/router.umd.js', + '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', + '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', + // other libraries + 'rxjs': 'npm:rxjs', + 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' + }, + // packages tells the System loader how to load when no filename and/or no extension + packages: { + app: { + main: './app/main.js', + defaultExtension: 'js' + }, + rxjs: { + defaultExtension: 'js' + } + } + }); +})(this); diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/lib.html b/public/docs/_examples/angular-in-dotnet-core/ts/lib.html new file mode 100644 index 0000000000..a6abf96720 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/lib.html @@ -0,0 +1,12 @@ +<!-- #docregion --> +<!-- 1. Load libraries --> +<!-- Polyfill for older browsers --> +<script src="~/node_modules/core-js/client/shim.min.js"></script> +<script src="~/node_modules/zone.js/dist/zone.js"></script> +<script src="~/node_modules/reflect-metadata/Reflect.js"></script> +<script src="~/node_modules/systemjs/dist/system.src.js"></script> +<!-- 2. Configure SystemJS --> +<script src="~/app/systemjs.config.js"></script> +<script> + System.import('app').catch(function(err){ console.error(err); }); +</script> diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/package1.json b/public/docs/_examples/angular-in-dotnet-core/ts/package1.json new file mode 100644 index 0000000000..b00ecdcfb5 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/package1.json @@ -0,0 +1,35 @@ +{ + "name": "angular-quickstart", + "version": "1.0.0", + "scripts": { + "tsc": "tsc", + "tsc:w": "tsc -w" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/angular/angular.io/blob/master/LICENSE" + } + ], + "dependencies": { + "@angular/common": "~2.2.0", + "@angular/compiler": "~2.2.0", + "@angular/core": "~2.2.0", + "@angular/forms": "~2.2.0", + "@angular/http": "~2.2.0", + "@angular/platform-browser": "~2.2.0", + "@angular/platform-browser-dynamic": "~2.2.0", + "@angular/router": "~3.2.0", + "@angular/upgrade": "~2.2.0", + "angular-in-memory-web-api": "~0.1.15", + "core-js": "^2.4.1", + "reflect-metadata": "^0.1.8", + "rxjs": "5.0.0-beta.12", + "systemjs": "0.19.39", + "zone.js": "^0.6.25" + }, + "devDependencies": { + "@types/core-js": "^0.9.34", + "typescript": "^2.0.3" + } +} diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json b/public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json new file mode 100644 index 0000000000..22f0a0d351 --- /dev/null +++ b/public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json @@ -0,0 +1,19 @@ +{ + "compileOnSave": true, + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": false + }, + "exclude": [ + "node_modules/*" + ], + "typeRoots": [ + "node_modules/@types/" + ] +} diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 97755b009c..ea755615ce 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -1,10 +1,11 @@ include ../_util-fns :marked - This cookbook describes how to build a .NET Core Web application with an Angular app running inside the MVC architecture. - .NET Core is cross platform. You can develop .NET Core application on Windows, MacOS or Linux, with tools of your own choices. This cookbook will describe how to build the application with Visual Studio 2015 on Windows. You can develop and run the project created in Visual Studio 2015 on all supported platforms with .NET Core CLI, but it is out of this cookbook’s scope, please refer to .NET Core official documentations. + .NET Core supports cross platforms. You can develop .NET Core application on Windows, MacOS or Linux and you can choose any tools. This cookbook will use Visual Studio 2015 on Windows. - This cookbook is focused on getting Angular app to work within .NET Core application. It does not explain how and why the angular code works. However this cookbook will provides all the code snippets required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular yet. However it is highly recommended that you should read the rest of the documentations to really understand how Angular works. + This cookbook does not explain how Angular or .NET Core work. Its task is to build an Angular app inside the MVC architecture in a .NET Core Web application. It will provide all the code snippets required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular or .NET Core yet. + + It is recommended that you follow this cookbook step by step and experience the challenges. a#toc :marked @@ -20,48 +21,57 @@ a#prerequisite .l-main-section :marked ## Prerequisite - 1. Download and install [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) - 1. Download and install [.NET Core Tools for visual studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) - 1. Download and Install [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) - 1. Download and install [Typescript 2 for visual studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) - 1. Download and install [Node.js Tools for visual studio 2015](https://aka.ms/getntvs) (optional) + + If you do not have them in your system, download and install the following items: + + 1. [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) + 1. [.NET Core Tools for visual studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) + 1. [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) + 1. [Typescript 2 for visual studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) + 1. [Node.js Tools for visual studio 2015](https://aka.ms/getntvs) (optional) a#create-dotnet-core-application .l-main-section :marked ## Create a new .NET Core Web Application - 1. Select `File` | `New` | `Project` from the menu - 1. In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` - 1. Select `ASP.NET Core Web Application (.NET Core)` template, give the project a name (this cookbook uses `AngularWithDotnetCore`), and click OK. - 1. Select `Web Application` and click OK. Wait for visual studio to restore packages. + In Visual Studio 2015: + + 1. Select `File` | `New` | `Project` from the menu + 1. In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` + 1. Select `ASP.NET Core Web Application (.NET Core)` template. + 1. Enter a name (for example `AngularWithDotnetCore`) for the project and Click OK. + 1. Select `Web Application` and click OK. + 1. Wait for visual studio to restore packages. a#create-angular-app .l-main-section :marked ## Create your Angular app - ### Create Configuration files for your Angular app. + ### Create Configuration files for your Angular app. - In the root folder, create `package.json` and `tsconfig.json` files. Populate them by pasting the contents below. + In the root directory, create the following `package.json` and `tsconfig.json` files: +makeTabs( - `angular-in-dotnet-core/ts/package.json, - angular-in-dotnet-core/ts/tsconfig.json`, + `angular-in-dotnet-core/ts/package1.json, + angular-in-dotnet-core/ts/tsconfig1.json`, null, `package.json, tsconfig.json` )(format='.') + When Visual Studio sees `package.json` file, it will install all specified npm packages automatically. If it does not, right click `package.json` file and select `Restore Packages`. + :marked ### Create your Angular app - Create an `app` subfolder off the project root directory. + Create an `app` folder in the root directory. + + Create the following files in the `app` folder: - Create the following files in the `app` subfolder: - +makeTabs( - `angular-in-dotnet-core/ts/app/systemjs.config.js, + `angular-in-dotnet-core/ts/app/systemjs.config.ts, angular-in-dotnet-core/ts/app/app.module.ts, angular-in-dotnet-core/ts/app/app.component.ts, angular-in-dotnet-core/ts/app/main.ts`, @@ -73,69 +83,80 @@ a#create-angular-app )(format='.') :marked - ### Edit `Views/shared/_layout.cshtml` to host the Angular application + ### Edit `Views/shared/_layout.cshtml` to host the Angular app - Open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `head` section. + For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `<head>` section. - To bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()` just after the navigation toolbar. ++makeExample('angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') +:marked + To bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()`. - The result should look like this: + The result should look like this: +makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked - Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the developer's tool, and in the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. + Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the console tab of the developer's tool in the browser, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. #### 404 Errors - These 404 errors indicate that the browser could not find files in `app` folder and `node_modules` folder. But we have an `app` folder and `node_modules` at the root of the project, why the browser cannot find it? + These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and an `node_modules` folder in the root directory of the project, why the browser can not find it? - #### Redirect request path to physical folder + It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder named `app` in `wwwroot` folder. + + In this case, the browser is searching for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` or `node_modules` folder into `wwwroot` folder, because: + + 1. You would have to work exclusively inside `wwwroot` folder for the angular app. - .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed as such so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder in `wwwroot` folder named `app`. + 1. You would have to manage npm packages outside of Visual Studio 2015. Because Visual Studio’s npm package manager only works when there is a `package.json` file in the root directory and it will only install npm packages into `node_modules` in root directory by default. - In this case, the browser is search for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` at root into `wwwroot` folder or move/copy `node_modules` folder into `wwwroot`, because: - 1. You would have to work exclusively inside `wwwroot` for angular app which is not ideal. - 1. You would have to manage the npm packages outside of Visual Studio 2015. Becuase visual studio’s npm package manager only works when there is a `package.json` file in the root project folder and the package manager will install npm packages into `node_modules` at root. + Fortunately, you can redirect the incoming requests to any chosen physical folders within the project. - Fortunately, you can redirect the incoming request path of `/app` and `/node_modules` to any chosen physical folder within the project. Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. + #### Redirect request path to physical folder + + Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. +makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect', 'startup.cs')(format='.') :marked - Remember to insert the following using statement to `startup.cs`: + Remember to insert the following `using` statements to `startup.cs`: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect-using', 'startup.cs')(format='.') :marked - The above code asks .NET Core to redirect any request asking for resources in `/app` and `/node_modules` to the physical `app` folder and `node_modules` folder at the root project folder. + With the above code in place, .NET Core will redirect all requests asking for resources in `/app` and `/node_modules` to the physical `app` and `node_modules` folders in the root project directory. - Rebuid and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. + Rebuild and run the application again, you will see "Hello Angular!" on top of the default MVC welcome message. a#move-app .l-main-section :marked ## Move Angular app to its own Controller and View - Now, you have seen that the Angular app is working. However, By boostraping it inside `Views/Shared/_layout.cshtml` for a quick test, you will find that every MVC pages bootstraps your Angular app. Let's move your Angular app into its own Controller and View, so that user can click a navigation link in the navbar and go to `/app` to start the Angular app. + Now, you have a working Angular app. However, By bootstrapping inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own Controller and View. ### Create Controller and View for the Angular app 1. Create a MVC Controller called `AppController` - 1. In Visual Studio, right click the `Controller` folder and select `Add` | `New Item...` + In Visual Studio: + + 1. Right click the `Controller` folder and select `Add` | `New Item...` 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. 1. Enter `AppController.cs` in the name box below and click `Add` button. - Angular app will use the `Index` action in side the generated `AppController` class, so you do not need to change anything in the `AppController` class. + Angular app will use the `Index` action of the generated `AppController` class. Therefore you do not need to change anything in the `AppController` class. - 1. Create the View for the `Index` action of `AppController` + 1. Create a View for the `Index` action of `AppController` - 1. Create a new `App` folder under `Views` folder at root + 1. Create a new `App` folder under `Views` folder 1. Right click the `App` folder and select `Add` | `New Item...` 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right 1. Leave the default name to `Index.cshtml` and click `Add` button. - 1. Open `Views/Shared/_layout.cshtml` and cut and paste the following code into `Views/App/Index.cshtml` + + Now let's populate above generated `Index.cshtml`: + + Open `Views/Shared/_layout.cshtml`, cut and paste the following code into `Views/App/Index.cshtml` ``` <!-- 2. Configure SystemJS --> <script src="~/app/systemjs.config.js"></script> @@ -143,47 +164,50 @@ a#move-app System.import('app').catch(function(err){ console.error(err); }); </script> ``` - 1. Cut and paste `<my-app>Loading…</my-app>` from `Views/Shared/_layout.cshtml` to `Views/App/Index.cshtml`. Wrap it in a `<div>` with minimum height of 300px. + + Also cut and paste `<my-app>Loading…</my-app>` from `Views/Shared/_layout.cshtml` to `Views/App/Index.cshtml`. Wrap it in a `<div>` with minimum height of 300px. The content of `Views/App/Index.cshtml` should look like this: +makeExample('angular-in-dotnet-core/ts/index.html', null, 'Views/App/Index.cshtml')(format='.') :marked - ### Add a navigation link to the top navbar + ### Add a navigation link + + Let's also add a navigation link to the top navigation bar, so that you can click and navigate to the Angular app. - Open `Views/Shared/_layout.cshtml`, under `<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>`, add: + Open `Views/Shared/_layout.cshtml`, under `<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>`, insert: +makeExample('angular-in-dotnet-core/ts/nav.html', null, 'Views/Shared/_layout.cshtml')(format='.') :marked ### Build and run - Press `F5` to build and run the project. Click `Angular App` in the top navigation, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page and click `Angular App` again, you will be navigated back to the Angular app. + Press `F5` to build and run the project. Click `Angular App` on the top navigation bar, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page. Click `Angular App` again, you will be navigated back to the Angular app. + + If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via Angular router. - If the Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via Angular router. - - In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) charpter and make it work inside .NET Core environment. + In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) chapter and make it work inside .NET Core environment. a#angular-app-with-routes .l-main-section :marked ## Angular app with routes - ### Download and copy the sample application + ### Download and copy the sample application - 1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of [Router & Navigation](../guide/router.html). Feel free to explore the app in Plunk before clicking the `Download your plunk as a ZIP file` button at the top right corner. + 1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of [Router & Navigation](../guide/router.html). Feel free to explore the app in Plunk before clicking the `Download your plunk as a ZIP file` button at the top right corner. - 1. Unzip the downloaded zip file to a folder and do the following: - * Open the extracted folder from your downloaded zip file, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. - * In Visual Studio, right click the `app` folder at the root, select `Open folder in File Explorer` to open your app folder, paste the above copied files, when promoted, select `Replace the files in the destination`. - - 1. Repeat the above steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your project. + 1. Unzip the downloaded zip file to a folder and do the following: + * Open the extracted folder, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. + * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer` to open your app folder. Then paste the above copied files. When promoted, select `Replace the files in the destination`. - Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. + 1. Repeat the above steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your .NET Core project. + + Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. ### Add Styles - To style your Angular app the same way as the sample application, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to `<title>` tag in the `<head>` section: + To style your Angular app the same way as the live example, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to `<title>` tag in the `<head>` section: +makeExample('angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') @@ -192,19 +216,19 @@ a#angular-app-with-routes Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - If you build and run the application and go to `Angular App`, you will that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + If you build and run the application and go to `Angular App`, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. - To fix the above error, open `/app/Systemjs.config.js` file, find ` main: './app/main.js'` and change it to `./main.js`. + To fix the above error, open `/app/Systemjs.config.js` file, find `main: './app/main.js'` and change it to `main: './main.js'`. - Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstraped but it is stopped due to errors. In the `Console` tab of the browser's `Developer tools`, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. + Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but it is stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. ### .NET Core's Pascal Case Urls - .NET Core parse urls to Pascale case by default. As you have seen, it does not work well with JavaScript frameworks like Angular. + .NET Core parse urls in Pascale case by default. As you saw above, it did not work well with JavaScript frameworks like Angular. - Fortunately, you can configure .NET Core to use lower case to parse its urls. + Fortunately, you can configure .NET Core to parse urls in lower case. - Open `startup.cs` file, in `ConfigureServices` method, insert the followling line before `service.AddMvc()`: + Open `startup.cs` file, in `ConfigureServices` method, insert the following line before `service.AddMvc();`: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls', 'startup.cs')(format='.') :marked @@ -212,15 +236,15 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') :marked - Now rebuild and run your application, the above error goes away. However only `Heros` and `login` links work as intended. The lazy load module `Crisis Center` and `Admin` are broken. In the Console, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. + Now rebuild and run your application, the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. ### Fix Lazy Loaded Modules - The problem is that Angular could not find the lazy loaded modules. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: + The problem is that Angular could not find the lazy loaded modules because their paths were wrong. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') :marked - The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you set the base href to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path because of the base href. + The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the base href to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path because of the base href. However, in the .NET Core environment, it works in a completely different way. It does not take base href into consideration. @@ -228,38 +252,39 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') :marked - Now, build and run, you will see that the Angular app is runing without errors until you refresh the browser. + Now, build and run, you will see that the Angular app is running without errors, until you refresh the browser. ## Configure .NET Core routes for Angular app - The Angular app has deep links, such as `/app/heros` and `/app/heros/11`. When you navigate inside the Angular app, it does not send any request to the .NET Core server. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. + The Angular app has deep links, such as `/app/heroes` and `/app/heroes/11`. When you navigate inside the Angular app, it does not send any requests to the .NET Core server. The Angular Router handles the routing on its own. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. - When .NET Core a request url, it tries to match its routes configration. The current route setting is as follow in the `startup.cs` file: + When .NET Core receive a request url, it tries to match its routes configuration. The current route setting in the `startup.cs` file is as follow: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') :marked - In this case, when .NET Core sees `/app/heros` url, it will try to excute `AppController`'s `Heros` action, which does not exist. + In this case, when .NET Core sees `/app/heroes` url, it will try to execute `AppController`'s `Heroes` action, which does not exist. + + In order to solve this problem, you can create a new route map and redirect all urls starting with `/app`(such as `/app/heroes`)to `/app`. Open `startup.cs` and change the routes to the following: - In order to solve this problem, you can create a new route map and redirect all url starting with `/app` to `/app`. Change the routes to this: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-new', 'startup.cs')(format='.') :marked - Notice the second `MapRoute`, it will ask .NET Core to excute `AppController`'s `Index` action for all urls starting with `app/`. + Notice the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`. - If you build and run the application and navigate to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. + If you build and run the application and navigate to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. a#summary .l-main-section :marked ## Summary - Angular application can live inside of a larger .NET Core web application. There are a few challenges: + Angular app can live inside the MVC architecture in a larger .NET Core web application. There are a few challenges: - 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request path to physical path in the root folder. It enables visual studio to manage npm packages for your. It also allow you to use any folder inside the project for your Angular app. + 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables visual studio to manage npm packages for you. It also allow you to use any folder inside the project for your Angular app. - 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular. You can configure .NET Core to parse lower case urls. + 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular Router. You can configure .NET Core to parse lower case urls. 1. Angular router uses `base href` but .NET Core ignores it. Angular app has to use relative path for its lazy loaded modules. - 1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. + 1. Angular app's deep links does not play well with .NET Core server side routing. You can configure .NET Core routing to redirect all urls starting with `/app` to the same MVC Controller and Action. From cf3f0c8fed36a84f36a5bcc842556e8c5b81df39 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 13:25:58 +0000 Subject: [PATCH 08/23] minor correction --- public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index ea755615ce..8e659514db 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -49,7 +49,7 @@ a#create-angular-app :marked ## Create your Angular app - ### Create Configuration files for your Angular app. + ### Create configuration files for your Angular app. In the root directory, create the following `package.json` and `tsconfig.json` files: From 91f187e83326a1e75d16bfdf715684d7fe3f94b3 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 13:34:14 +0000 Subject: [PATCH 09/23] minor corrections --- .../ts/latest/cookbook/angular-in-dotnet-core.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 8e659514db..e3d03439e5 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -60,10 +60,9 @@ a#create-angular-app `package.json, tsconfig.json` )(format='.') - +:marked When Visual Studio sees `package.json` file, it will install all specified npm packages automatically. If it does not, right click `package.json` file and select `Restore Packages`. -:marked ### Create your Angular app Create an `app` folder in the root directory. @@ -85,9 +84,10 @@ a#create-angular-app :marked ### Edit `Views/shared/_layout.cshtml` to host the Angular app - For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `<head>` section. + For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `<head>` section: +makeExample('angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') + :marked To bootstrap the Angular app, also insert `<my-app>Loading…</my-app>` above `@RenderBody()`. @@ -100,9 +100,9 @@ a#create-angular-app #### 404 Errors - These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and an `node_modules` folder in the root directory of the project, why the browser can not find it? + These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and a `node_modules` folder in the root directory, why the browser can not find it? - It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's designed so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder named `app` in `wwwroot` folder. + It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder named `app` in the `wwwroot` folder. In this case, the browser is searching for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` or `node_modules` folder into `wwwroot` folder, because: From b150246e170ebfee96d3faef02c21721a367a4c9 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 14:09:49 +0000 Subject: [PATCH 10/23] reviews --- .../cookbook/angular-in-dotnet-core.jade | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index e3d03439e5..a436c6b143 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -1,11 +1,11 @@ include ../_util-fns :marked - .NET Core supports cross platforms. You can develop .NET Core application on Windows, MacOS or Linux and you can choose any tools. This cookbook will use Visual Studio 2015 on Windows. + This cookbook describes how to build an Angular app inside the MVC architecture in a .NET Core Web application. It does not explain how Angular or .NET Core work. However it will provide all the code snippets required. Therefore you will be able to follow through this cookbook even if you know nothing about Angular or .NET Core yet. - This cookbook does not explain how Angular or .NET Core work. Its task is to build an Angular app inside the MVC architecture in a .NET Core Web application. It will provide all the code snippets required for you. Therefore you will be able to follow through this cookbook even if you know nothing about Angular or .NET Core yet. + It is recommended that you follow this cookbook step by step and experience the challenges in the process. - It is recommended that you follow this cookbook step by step and experience the challenges. + .NET Core supports cross platforms. You can develop .NET Core application on Windows, MacOS or Linux and you can choose any tools. This cookbook will use Visual Studio 2015 on Windows. a#toc :marked @@ -104,11 +104,11 @@ a#create-angular-app It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder named `app` in the `wwwroot` folder. - In this case, the browser is searching for `app` and `node_modules` physical folders in `wwwroot` folder. You do not want to move the `app` or `node_modules` folder into `wwwroot` folder, because: + In this case, the browser is searching for physical `app` and `node_modules` folders in `wwwroot` folder. You do not want to move `app` or `node_modules` folders into `wwwroot` folder, because: 1. You would have to work exclusively inside `wwwroot` folder for the angular app. - 1. You would have to manage npm packages outside of Visual Studio 2015. Because Visual Studio’s npm package manager only works when there is a `package.json` file in the root directory and it will only install npm packages into `node_modules` in root directory by default. + 1. You would have to manage npm packages outside of Visual Studio 2015. Because Visual Studio’s npm package manager only works when there is a `package.json` file in the root directory and it will only install npm packages into a `node_modules` folder in root directory. Fortunately, you can redirect the incoming requests to any chosen physical folders within the project. @@ -131,11 +131,11 @@ a#create-angular-app a#move-app .l-main-section :marked - ## Move Angular app to its own Controller and View + ## Move Angular app to its own MVC Controller and View - Now, you have a working Angular app. However, By bootstrapping inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own Controller and View. + Now, you have a working Angular app. However, By bootstrapping inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own MVC Controller and View. - ### Create Controller and View for the Angular app + ### Create MVC Controller and View for the Angular app 1. Create a MVC Controller called `AppController` @@ -154,7 +154,7 @@ a#move-app 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right 1. Leave the default name to `Index.cshtml` and click `Add` button. - Now let's populate above generated `Index.cshtml`: + Now let's populate above generated `Views/App/Index.cshtml`: Open `Views/Shared/_layout.cshtml`, cut and paste the following code into `Views/App/Index.cshtml` ``` @@ -184,7 +184,7 @@ a#move-app Press `F5` to build and run the project. Click `Angular App` on the top navigation bar, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page. Click `Angular App` again, you will be navigated back to the Angular app. - If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app would have many pages with many modules. It would also lazy load modules via Angular router. + If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app has many pages with many modules. It would also lazy load modules via Angular router. In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) chapter and make it work inside .NET Core environment. @@ -198,13 +198,13 @@ a#angular-app-with-routes 1. Click [here](https://angular.io/resources/live-examples/router/ts/plnkr.html) to open the live example of [Router & Navigation](../guide/router.html). Feel free to explore the app in Plunk before clicking the `Download your plunk as a ZIP file` button at the top right corner. 1. Unzip the downloaded zip file to a folder and do the following: - * Open the extracted folder, you will find an `app` folder inside. Open this `app` folder and copy everything to clipboard. + * Open the extracted folder, you will find an `app` folder. Open it and copy everything to clipboard. * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer` to open your app folder. Then paste the above copied files. When promoted, select `Replace the files in the destination`. - 1. Repeat the above steps, copy `styles.css` from the extracted folder into `wwwroot/css` folder in your .NET Core project. - Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. + 1. Repeat the above steps, copy `styles.css` from the extracted folder to `wwwroot/css` folder in your .NET Core project. + ### Add Styles To style your Angular app the same way as the live example, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to `<title>` tag in the `<head>` section: @@ -212,11 +212,11 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') :marked - ### Set base href + ### Set `base href` - Base href is required by Angular Router. Because the Angular app is under .NET Core's `App` route, you will set the base href to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. + `Base href` is required by Angular Router. Because the Angular app is served by `AppController` and it uses .NET Core's `App` route, you will set the `base href` to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - If you build and run the application and go to `Angular App`, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because base href is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + If you build and run the application and navigate to `Angular App`, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. To fix the above error, open `/app/Systemjs.config.js` file, find `main: './app/main.js'` and change it to `main: './main.js'`. @@ -224,7 +224,7 @@ a#angular-app-with-routes ### .NET Core's Pascal Case Urls - .NET Core parse urls in Pascale case by default. As you saw above, it did not work well with JavaScript frameworks like Angular. + .NET Core parses urls in Pascale case by default. As you saw above, it did not work well with JavaScript framework like Angular. Fortunately, you can configure .NET Core to parse urls in lower case. @@ -244,11 +244,11 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') :marked - The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the base href to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` in the path because of the base href. + The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the `base href` to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` because of the `base href`. - However, in the .NET Core environment, it works in a completely different way. It does not take base href into consideration. + However, in the .NET Core environment, it works in a completely different way. It does not take `base href` into consideration. - To fix the issue, simple use relative path like this: + To fix the issue, simply use relative path like this: +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') :marked @@ -258,7 +258,7 @@ a#angular-app-with-routes The Angular app has deep links, such as `/app/heroes` and `/app/heroes/11`. When you navigate inside the Angular app, it does not send any requests to the .NET Core server. The Angular Router handles the routing on its own. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. - When .NET Core receive a request url, it tries to match its routes configuration. The current route setting in the `startup.cs` file is as follow: + When .NET Core receive a request url, it tries to match with its route configuration. The current route setting in the `startup.cs` file is as follow: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') @@ -281,7 +281,7 @@ a#summary Angular app can live inside the MVC architecture in a larger .NET Core web application. There are a few challenges: - 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables visual studio to manage npm packages for you. It also allow you to use any folder inside the project for your Angular app. + 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables visual studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular Router. You can configure .NET Core to parse lower case urls. From a6469a7473025c14cea1ca02b8114938f0e231b0 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 14:53:54 +0000 Subject: [PATCH 11/23] further review. --- .../cookbook/angular-in-dotnet-core.jade | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index a436c6b143..6a97093a3a 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -61,7 +61,7 @@ a#create-angular-app tsconfig.json` )(format='.') :marked - When Visual Studio sees `package.json` file, it will install all specified npm packages automatically. If it does not, right click `package.json` file and select `Restore Packages`. + When Visual Studio sees `package.json` file, it will install all specified npm packages automatically. You can also right click `package.json` file and select `Restore Packages`. ### Create your Angular app @@ -84,7 +84,7 @@ a#create-angular-app :marked ### Edit `Views/shared/_layout.cshtml` to host the Angular app - For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` in the `<head>` section: + For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` script into the `<head>` section: +makeExample('angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') @@ -96,17 +96,17 @@ a#create-angular-app +makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked - Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the console tab of the developer's tool in the browser, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. + Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the the developer's tool in the browser, go to the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. #### 404 Errors These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and a `node_modules` folder in the root directory, why the browser can not find it? - It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical folder named `app` in the `wwwroot` folder. + It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical `app` folder in the `wwwroot` folder. - In this case, the browser is searching for physical `app` and `node_modules` folders in `wwwroot` folder. You do not want to move `app` or `node_modules` folders into `wwwroot` folder, because: + In this case, the browser is searching for physical `app` and `node_modules` folders in `wwwroot` folder. You do not want to move `app` or `node_modules` folder into the `wwwroot` folder, because: - 1. You would have to work exclusively inside `wwwroot` folder for the angular app. + 1. You would have to work exclusively inside the `wwwroot` folder for the angular app. 1. You would have to manage npm packages outside of Visual Studio 2015. Because Visual Studio’s npm package manager only works when there is a `package.json` file in the root directory and it will only install npm packages into a `node_modules` folder in root directory. @@ -133,7 +133,7 @@ a#move-app :marked ## Move Angular app to its own MVC Controller and View - Now, you have a working Angular app. However, By bootstrapping inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own MVC Controller and View. + Now, you have a working Angular app. However, By bootstrapping the app inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own MVC Controller and View. ### Create MVC Controller and View for the Angular app @@ -145,14 +145,14 @@ a#move-app 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. 1. Enter `AppController.cs` in the name box below and click `Add` button. - Angular app will use the `Index` action of the generated `AppController` class. Therefore you do not need to change anything in the `AppController` class. + Angular app will use the generated `Index` action of `AppController` class. Therefore you do not need to change anything in the `AppController` class. - 1. Create a View for the `Index` action of `AppController` + 1. Create a View for the `Index` action 1. Create a new `App` folder under `Views` folder - 1. Right click the `App` folder and select `Add` | `New Item...` + 1. Right click the `Views/App` folder and select `Add` | `New Item...` 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right - 1. Leave the default name to `Index.cshtml` and click `Add` button. + 1. Leave the default name as `Index.cshtml` and click `Add` button. Now let's populate above generated `Views/App/Index.cshtml`: @@ -184,7 +184,7 @@ a#move-app Press `F5` to build and run the project. Click `Angular App` on the top navigation bar, you will see `Hello Angular!`. Click `About` and the app will navigate to the default `About` page. Click `Angular App` again, you will be navigated back to the Angular app. - If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app has many pages with many modules. It would also lazy load modules via Angular router. + If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app has many pages and modules. It would also lazy load modules via Angular router. In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) chapter and make it work inside .NET Core environment. @@ -199,7 +199,7 @@ a#angular-app-with-routes 1. Unzip the downloaded zip file to a folder and do the following: * Open the extracted folder, you will find an `app` folder. Open it and copy everything to clipboard. - * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer` to open your app folder. Then paste the above copied files. When promoted, select `Replace the files in the destination`. + * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer`. Then paste the above copied files. When promoted, select `Replace the files in the destination`. Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. @@ -214,13 +214,13 @@ a#angular-app-with-routes :marked ### Set `base href` - `Base href` is required by Angular Router. Because the Angular app is served by `AppController` and it uses .NET Core's `App` route, you will set the `base href` to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. + `Base href` is required by Angular Router. Because the Angular app is served by `AppController` and it uses .NET Core's `App` route, you need to set the `base href` to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - If you build and run the application and navigate to `Angular App`, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Notice the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + If you build and run the application and navigate to Angular app, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Note the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. To fix the above error, open `/app/Systemjs.config.js` file, find `main: './app/main.js'` and change it to `main: './main.js'`. - Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but it is stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. + Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. ### .NET Core's Pascal Case Urls @@ -228,7 +228,7 @@ a#angular-app-with-routes Fortunately, you can configure .NET Core to parse urls in lower case. - Open `startup.cs` file, in `ConfigureServices` method, insert the following line before `service.AddMvc();`: + Open `startup.cs` file, in `ConfigureServices` method, insert the following line above `service.AddMvc();`: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls', 'startup.cs')(format='.') :marked @@ -236,7 +236,7 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') :marked - Now rebuild and run your application, the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Notice the absence of `/app/` in the path. + Now rebuild and run your application, the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Note the absence of `/app/` in the path. ### Fix Lazy Loaded Modules @@ -244,7 +244,7 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') :marked - The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value start with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the `base href` to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already has `app` because of the `base href`. + The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value starting with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the `base href` to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already contains `app` because of the `base href`. However, in the .NET Core environment, it works in a completely different way. It does not take `base href` into consideration. @@ -258,19 +258,19 @@ a#angular-app-with-routes The Angular app has deep links, such as `/app/heroes` and `/app/heroes/11`. When you navigate inside the Angular app, it does not send any requests to the .NET Core server. The Angular Router handles the routing on its own. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. - When .NET Core receive a request url, it tries to match with its route configuration. The current route setting in the `startup.cs` file is as follow: + When .NET Core receive a request url, it tries to match with its route configuration. The current route configuration in the `startup.cs` file is as follow: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') :marked In this case, when .NET Core sees `/app/heroes` url, it will try to execute `AppController`'s `Heroes` action, which does not exist. - In order to solve this problem, you can create a new route map and redirect all urls starting with `/app`(such as `/app/heroes`)to `/app`. Open `startup.cs` and change the routes to the following: + In order to solve this problem, you can create a new route map and redirect all urls starting with `/app`(e.g. `/app/heroes`)to `/app`. Open `startup.cs` and change the route configuration to the following: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-new', 'startup.cs')(format='.') :marked - Notice the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`. + Note the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`. If you build and run the application and navigate to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. From db4a8407e830db6718ef15568210b35f290f7bc4 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 14:57:13 +0000 Subject: [PATCH 12/23] minor --- public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 6a97093a3a..826bb43330 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -279,7 +279,7 @@ a#summary :marked ## Summary - Angular app can live inside the MVC architecture in a larger .NET Core web application. There are a few challenges: + Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcome the following challenges: 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables visual studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. From e44c18b3db2aefd6dcc82182144a873fa9ba925e Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 15:18:52 +0000 Subject: [PATCH 13/23] Add angular in .net core to navigation menu. --- public/docs/dart/latest/cookbook/_data.json | 7 +++++++ public/docs/js/latest/cookbook/_data.json | 6 ++++++ public/docs/ts/latest/cookbook/_data.json | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/public/docs/dart/latest/cookbook/_data.json b/public/docs/dart/latest/cookbook/_data.json index eb1a46ace4..44ac3a80c1 100644 --- a/public/docs/dart/latest/cookbook/_data.json +++ b/public/docs/dart/latest/cookbook/_data.json @@ -68,5 +68,12 @@ "title": "Visual Studio 2015 QuickStart", "intro": "Use Visual Studio 2015 with the QuickStart files", "hide": true + }, + + "angular-in-dotnet-core": { + "title": "Angular in .NET Core", + "intro": "Angular app in .NET Core MVC architecture", + "hide": true } + } diff --git a/public/docs/js/latest/cookbook/_data.json b/public/docs/js/latest/cookbook/_data.json index 74ee2a0be9..650603bda3 100644 --- a/public/docs/js/latest/cookbook/_data.json +++ b/public/docs/js/latest/cookbook/_data.json @@ -61,6 +61,12 @@ "visual-studio-2015": { "title": "Visual Studio 2015 QuickStart", "intro": "Use Visual Studio 2015 with the QuickStart files" + }, + + "angular-in-dotnet-core": { + "title": "Angular in .NET Core", + "intro": "Angular app in .NET Core MVC architecture", + "hide": true } } diff --git a/public/docs/ts/latest/cookbook/_data.json b/public/docs/ts/latest/cookbook/_data.json index 78b159e40c..b77e0d9b64 100644 --- a/public/docs/ts/latest/cookbook/_data.json +++ b/public/docs/ts/latest/cookbook/_data.json @@ -64,5 +64,10 @@ "visual-studio-2015": { "title": "Visual Studio 2015 QuickStart", "intro": "Use Visual Studio 2015 with the QuickStart files" + }, + + "angular-in-dotnet-core": { + "title": "Angular in .NET Core", + "intro": "Angular app in .NET Core MVC architecture" } } From 427f7fc325a573f00d66da25c464fb9bff3d92ce Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 15:58:07 +0000 Subject: [PATCH 14/23] remove comment in systemjs.config --- .../_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts index 6d195ae911..eca8682e5f 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts @@ -11,8 +11,6 @@ }, // map tells the System loader where to look for things map: { - // our app is within the app folder - // base href is set to "app" for routing which does the same thing "app:'app'" below, therefore we have to remove the "app" here. app: '', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', From 2985455fd6276ef6b617f06e405a1cb1e7cb4ceb Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 16:01:03 +0000 Subject: [PATCH 15/23] minor changes to layout. --- .../docs/_examples/angular-in-dotnet-core/ts/_layout.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html b/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html index a4d6ebab63..daf3fb9745 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html +++ b/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html @@ -23,14 +23,14 @@ <script src="~/node_modules/zone.js/dist/zone.js"></script> <script src="~/node_modules/reflect-metadata/Reflect.js"></script> <script src="~/node_modules/systemjs/dist/system.src.js"></script> - <!-- 2. Configure SystemJS --> + <!-- 2. Configure SystemJS --> <script src="~/app/systemjs.config.js"></script> <script> System.import('app').catch(function(err){ console.error(err); }); </script> </head> <body> - + <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> @@ -52,6 +52,7 @@ </div> </div> <div class="container body-content"> + <!-- 3. Bootstrap Angular app--> <my-app>Loading…</my-app> @RenderBody() <hr /> @@ -79,4 +80,4 @@ @RenderSection("scripts", required: false) </body> - </html> \ No newline at end of file + </html> From 29ac24c86a3c1c64aefc872cb151ba9c5c62ade6 Mon Sep 17 00:00:00 2001 From: Rex <rexebin@gmail.com> Date: Mon, 21 Nov 2016 16:12:02 +0000 Subject: [PATCH 16/23] Update angular-in-dotnet-core.jade --- .../cookbook/angular-in-dotnet-core.jade | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 826bb43330..0994d14a73 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -1,11 +1,11 @@ include ../_util-fns :marked - This cookbook describes how to build an Angular app inside the MVC architecture in a .NET Core Web application. It does not explain how Angular or .NET Core work. However it will provide all the code snippets required. Therefore you will be able to follow through this cookbook even if you know nothing about Angular or .NET Core yet. + This cookbook describes how to build an Angular app inside the MVC architecture in a .NET Core Web application. It does not explain how Angular or .NET Core works. However it will provide all the code snippets required. Therefore you will be able to follow through this cookbook even if you are currently not familiar with Angular or .NET Core. It is recommended that you follow this cookbook step by step and experience the challenges in the process. - .NET Core supports cross platforms. You can develop .NET Core application on Windows, MacOS or Linux and you can choose any tools. This cookbook will use Visual Studio 2015 on Windows. + .NET Core supports cross platforms. You can develop .NET Core applications on Windows, macOS or Linux. This cookbook will use Visual Studio 2015 on Windows. a#toc :marked @@ -25,10 +25,10 @@ a#prerequisite If you do not have them in your system, download and install the following items: 1. [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) - 1. [.NET Core Tools for visual studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) + 1. [.NET Core Tools for Vvisual Studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) 1. [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) - 1. [Typescript 2 for visual studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) - 1. [Node.js Tools for visual studio 2015](https://aka.ms/getntvs) (optional) + 1. [Typescript 2 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) + 1. [Node.js Tools for Visual Studio 2015](https://aka.ms/getntvs) (optional) a#create-dotnet-core-application .l-main-section @@ -40,9 +40,9 @@ a#create-dotnet-core-application 1. Select `File` | `New` | `Project` from the menu 1. In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` 1. Select `ASP.NET Core Web Application (.NET Core)` template. - 1. Enter a name (for example `AngularWithDotnetCore`) for the project and Click OK. + 1. Enter a name (for example `AngularWithDotnetCore`) for the project and click OK. 1. Select `Web Application` and click OK. - 1. Wait for visual studio to restore packages. + 1. Wait for Visual Studio to restore packages. a#create-angular-app .l-main-section @@ -61,7 +61,7 @@ a#create-angular-app tsconfig.json` )(format='.') :marked - When Visual Studio sees `package.json` file, it will install all specified npm packages automatically. You can also right click `package.json` file and select `Restore Packages`. + When `package.json` is created, the Visual Studio will automatically install all specified npm packages. You can also right click the `package.json` file and select `Restore Packages`. ### Create your Angular app @@ -84,7 +84,7 @@ a#create-angular-app :marked ### Edit `Views/shared/_layout.cshtml` to host the Angular app - For a quick start, open `Views/shared/_layout.cshtml` file and insert Angular app’s libraries and `systemjs.config.js` script into the `<head>` section: + For a quick start, open `Views/shared/_layout.cshtml` and insert Angular app’s libraries and `systemjs.config.js` script into the `<head>` section: +makeExample('angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') @@ -102,11 +102,11 @@ a#create-angular-app These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and a `node_modules` folder in the root directory, why the browser can not find it? - It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It's by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical `app` folder in the `wwwroot` folder. + It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It is by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical `app` folder in the `wwwroot` folder. - In this case, the browser is searching for physical `app` and `node_modules` folders in `wwwroot` folder. You do not want to move `app` or `node_modules` folder into the `wwwroot` folder, because: + In this case, the browser is searching for physical `app` and `node_modules` folders in `wwwroot` folder. You do not want to move the `app` or the `node_modules` folder into the `wwwroot` folder, because: - 1. You would have to work exclusively inside the `wwwroot` folder for the angular app. + 1. You would have to work exclusively inside the `wwwroot` folder for the Angular app. 1. You would have to manage npm packages outside of Visual Studio 2015. Because Visual Studio’s npm package manager only works when there is a `package.json` file in the root directory and it will only install npm packages into a `node_modules` folder in root directory. @@ -114,7 +114,7 @@ a#create-angular-app #### Redirect request path to physical folder - Open your `startup.cs` file and insert the following code under line `app.UseStaticFiles();`. + Open your `startup.cs` file and insert the following code under the line `app.UseStaticFiles();`. +makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect', 'startup.cs')(format='.') @@ -133,7 +133,7 @@ a#move-app :marked ## Move Angular app to its own MVC Controller and View - Now, you have a working Angular app. However, By bootstrapping the app inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own MVC Controller and View. + Now, you have a working Angular app. However, by bootstrapping the app inside `Views/Shared/_layout.cshtml`, you will find that every MVC page bootstraps the app. Let's move your Angular app into its own MVC Controller and View. ### Create MVC Controller and View for the Angular app @@ -145,7 +145,7 @@ a#move-app 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC Controller Class` on the right. 1. Enter `AppController.cs` in the name box below and click `Add` button. - Angular app will use the generated `Index` action of `AppController` class. Therefore you do not need to change anything in the `AppController` class. + Angular app will use the generated `Index` action of the `AppController` class. Therefore you do not need to change anything in the `AppController` class. 1. Create a View for the `Index` action @@ -154,7 +154,7 @@ a#move-app 1. In the `Add New Item` dialog, choose `ASP.NET` on the left and then `MVC View page` on the right 1. Leave the default name as `Index.cshtml` and click `Add` button. - Now let's populate above generated `Views/App/Index.cshtml`: + Now let's populate the above generated `Views/App/Index.cshtml`: Open `Views/Shared/_layout.cshtml`, cut and paste the following code into `Views/App/Index.cshtml` ``` @@ -186,7 +186,7 @@ a#move-app If your Angular app has only one page, this would be the end of this cookbook. However, a typical Angular app has many pages and modules. It would also lazy load modules via Angular router. - In the following sections, you will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) chapter and make it work inside .NET Core environment. + In the following sections, we will replace the above basic Angular app with the live example in [Router & Navigation](../guide/router.html) chapter and make it work inside the .NET Core environment. a#angular-app-with-routes .l-main-section @@ -199,7 +199,7 @@ a#angular-app-with-routes 1. Unzip the downloaded zip file to a folder and do the following: * Open the extracted folder, you will find an `app` folder. Open it and copy everything to clipboard. - * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer`. Then paste the above copied files. When promoted, select `Replace the files in the destination`. + * In Visual Studio, right click the `app` folder in the root directory and select `Open folder in File Explorer`. Then paste the above copied files. When prompted, select `Replace the files in the destination`. Your `app` folder in the .NET Core project should contain everything in the downloaded `app` folder and `systemjs.config.js` file created previously. @@ -207,7 +207,7 @@ a#angular-app-with-routes ### Add Styles - To style your Angular app the same way as the live example, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to `<title>` tag in the `<head>` section: + To style your Angular app the same way as the live example, open `Views/Shared/_layout.cshtml` and insert the following `<link>` tag next to the `<title>` tag in the `<head>` section: +makeExample('angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') @@ -216,15 +216,15 @@ a#angular-app-with-routes `Base href` is required by Angular Router. Because the Angular app is served by `AppController` and it uses .NET Core's `App` route, you need to set the `base href` to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - If you build and run the application and navigate to Angular app, you will find that your angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Note the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + If you build and run the application and navigate to Angular app, you will find that your Angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Note the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. - To fix the above error, open `/app/Systemjs.config.js` file, find `main: './app/main.js'` and change it to `main: './main.js'`. + To fix the above error, open `/app/Systemjs.config.js`, find `main: './app/main.js'` and change it to `main: './main.js'`. Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. ### .NET Core's Pascal Case Urls - .NET Core parses urls in Pascale case by default. As you saw above, it did not work well with JavaScript framework like Angular. + .NET Core parses urls in Pascal case by default. As you have seen above, it does not work well with JavaScript framework like Angular. Fortunately, you can configure .NET Core to parse urls in lower case. @@ -236,11 +236,11 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') :marked - Now rebuild and run your application, the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Note the absence of `/app/` in the path. + Now rebuild and run your application and you will find the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Note the absence of `/app/` in the path. ### Fix Lazy Loaded Modules - The problem is that Angular could not find the lazy loaded modules because their paths were wrong. Let's check out `app-routing.module.ts` file in `app` folder, you can see the following: + The problem is that Angular could not find the lazy loaded modules because their paths were wrong. Let's check out the `app-routing.module.ts` file in the `app` folder. You can see the following: +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') :marked @@ -252,13 +252,13 @@ a#angular-app-with-routes +makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') :marked - Now, build and run, you will see that the Angular app is running without errors, until you refresh the browser. + Now, build and run. You will see that the Angular app is running without errors, until you refresh the browser. ## Configure .NET Core routes for Angular app - The Angular app has deep links, such as `/app/heroes` and `/app/heroes/11`. When you navigate inside the Angular app, it does not send any requests to the .NET Core server. The Angular Router handles the routing on its own. However, when you refresh the browser with deep links, the browser send request to .NET Core server and expect .NET Core to response. + The Angular app has deep links, such as `/app/heroes` and `/app/heroes/11`. When you navigate inside the Angular app, it does not send any requests to the .NET Core server. The Angular Router handles routing on its own. However, when you refresh the browser with deep links, the browser send requests to .NET Core server and expect .NET Core to respond. - When .NET Core receive a request url, it tries to match with its route configuration. The current route configuration in the `startup.cs` file is as follow: + When .NET Core receives a request url, it tries to match with its route configuration. The current route configuration in the `startup.cs` file is as follow: +makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') @@ -272,16 +272,16 @@ a#angular-app-with-routes :marked Note the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`. - If you build and run the application and navigate to the Angular app, then refresh the browser, you will find that the Angular app is now working as intended. + If you build and run the application,navigate to the Angular app, and refresh the browser, you will find that the Angular app is now working as intended. a#summary .l-main-section :marked ## Summary - Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcome the following challenges: + Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcomed the following challenges: - 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables visual studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. + 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables the Visual Studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular Router. You can configure .NET Core to parse lower case urls. From 7d0044815c4e268d5ba99fdb305602d2b64ea393 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 16:19:28 +0000 Subject: [PATCH 17/23] review is done. --- .../ts/latest/cookbook/angular-in-dotnet-core.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 0994d14a73..f6728ef9b1 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -25,7 +25,7 @@ a#prerequisite If you do not have them in your system, download and install the following items: 1. [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) - 1. [.NET Core Tools for Vvisual Studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) + 1. [.NET Core Tools for Visual Studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) 1. [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) 1. [Typescript 2 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) 1. [Node.js Tools for Visual Studio 2015](https://aka.ms/getntvs) (optional) @@ -96,7 +96,7 @@ a#create-angular-app +makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked - Now, if you build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the the developer's tool in the browser, go to the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. + Now, build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the the developer's tool in the browser, go to the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. #### 404 Errors @@ -216,11 +216,11 @@ a#angular-app-with-routes `Base href` is required by Angular Router. Because the Angular app is served by `AppController` and it uses .NET Core's `App` route, you need to set the `base href` to `/app/`. Open `Views/Shared/_layout.cshtml` and insert `<base href="/app/"/>` inside the `<head>` section as the first child. - If you build and run the application and navigate to Angular app, you will find that your Angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Note the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. + Build and run the application and navigate to Angular app, you will find that your Angular app is broken and there is an error in the console: `GET http://localhost:55771/app/app/main.js 404 (Not Found)`. Note the double `/app/app`. It is because `base href` is set to `/app/` and as a result all JavaScript requests are prefixed with `/app/`. To fix the above error, open `/app/Systemjs.config.js`, find `main: './app/main.js'` and change it to `main: './main.js'`. - Now, if you build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. + Now, Build and run the project and navigate to the Angular app, you will see that the app is bootstrapped but stopped due to errors. In the console tab, Angular is complaining that it `Cannot match any routes. URL Segment: 'App'`. ### .NET Core's Pascal Case Urls @@ -272,7 +272,7 @@ a#angular-app-with-routes :marked Note the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`. - If you build and run the application,navigate to the Angular app, and refresh the browser, you will find that the Angular app is now working as intended. + Build and run the application,navigate to the Angular app, and refresh the browser, you will find that the Angular app is now working as intended. a#summary .l-main-section From 80229e86eaf972e96cd48bd4bc7f5ee0be4e9af2 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 16:31:13 +0000 Subject: [PATCH 18/23] minor correction. --- public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index f6728ef9b1..b5f5b2b4dc 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -279,7 +279,7 @@ a#summary :marked ## Summary - Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcomed the following challenges: + Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcome the following challenges: 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables the Visual Studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. From 3360fb7ed8c303c9dd320e7aad4ddbdc42bcafbd Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Mon, 21 Nov 2016 16:41:07 +0000 Subject: [PATCH 19/23] minor correction. --- public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index b5f5b2b4dc..028e0f92c7 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -61,7 +61,7 @@ a#create-angular-app tsconfig.json` )(format='.') :marked - When `package.json` is created, the Visual Studio will automatically install all specified npm packages. You can also right click the `package.json` file and select `Restore Packages`. + When `package.json` is created, Visual Studio will automatically install all specified npm packages. You can also right click the `package.json` file and select `Restore Packages`. ### Create your Angular app @@ -281,7 +281,7 @@ a#summary Angular app can live inside the MVC architecture in a larger .NET Core web application. This cookbook has overcome the following challenges: - 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables the Visual Studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. + 1. .NET Core only exposes `wwwroot` to the client. This cookbook teaches you how to configure .NET Core to redirect request paths to physical paths in the root directory. It enables Visual Studio to manage npm packages for you. It also allows you to use any folder inside the project for your Angular app. 1. .NET Core uses Pascal case to parse urls, which does not play well with Angular Router. You can configure .NET Core to parse lower case urls. From 37d3e9f43e441ea38a917bbbd242259dc64845a2 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Tue, 22 Nov 2016 10:37:19 +0000 Subject: [PATCH 20/23] =?UTF-8?q?Edit=20to=20reflect=20John=E2=80=99s=20co?= =?UTF-8?q?mments.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cookbook/angular-in-dotnet-core.jade | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 028e0f92c7..40bf25a646 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -1,11 +1,11 @@ include ../_util-fns :marked - This cookbook describes how to build an Angular app inside the MVC architecture in a .NET Core Web application. It does not explain how Angular or .NET Core works. However it will provide all the code snippets required. Therefore you will be able to follow through this cookbook even if you are currently not familiar with Angular or .NET Core. + This cookbook takes a hands-on approach to demonstrating how to build an Angular app inside the MVC architecture in a .NET Core Web application. It does not explain how Angular or .NET Core works. However it will provide all the code snippets required. Therefore you will be able to follow through this cookbook even if you are currently not familiar with Angular or .NET Core. - It is recommended that you follow this cookbook step by step and experience the challenges in the process. + If you want to host an Angular app inside .NET Core MVC architecture, you have come to the right place. - .NET Core supports cross platforms. You can develop .NET Core applications on Windows, macOS or Linux. This cookbook will use Visual Studio 2015 on Windows. + This cookbook will use Visual Studio 2015 on Windows. However .NET Core is a cross platform solution. You can follow this cookbook using .NET Core CLI and editor of your choice on Windows, MacOS or Linux. The principles described in this cookbook applies to all .NET Core Web Application with MVC architecture. a#toc :marked @@ -22,13 +22,13 @@ a#prerequisite :marked ## Prerequisite - If you do not have them in your system, download and install the following items: + Let's begin by downloading and installing the following requirements: - 1. [Visual studio 2015 Update 3](https://go.microsoft.com/fwlink/?LinkId=691129) - 1. [.NET Core Tools for Visual Studio 2015](https://go.microsoft.com/fwlink/?LinkId=691978) - 1. [.Net Core SDK](https://go.microsoft.com/fwlink/?LinkID=835014) - 1. [Typescript 2 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) - 1. [Node.js Tools for Visual Studio 2015](https://aka.ms/getntvs) (optional) + 1. [Visual Studio 2015 Update 3](https://download.microsoft.com/download/4/8/f/48f0645f-51b6-4733-b808-63e640cddaec/vs2015.3.exe) + 1. [.NET Core Tools for Visual Studio 2015](https://download.microsoft.com/download/F/6/E/F6ECBBCC-B02F-424E-8E03-D47E9FA631B7/DotNetCore.1.0.1-VS2015Tools.Preview2.0.3.exe) + 1. [.Net Core SDK](https://download.microsoft.com/download/1/4/1/141760B3-805B-4583-B17C-8C5BC5A876AB/Installers/dotnet-dev-win-x64.1.0.0-preview2-1-003177.exe) + 1. [TypeScript 2 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) + 1. [Node.js Tools for Visual Studio 2015](https://visualstudiogallery.msdn.microsoft.com/68faf8ac-b953-42f5-a908-55555deccf7a/file/206630/5/NTVS%201.2%20VS%202015.msi) (optional) a#create-dotnet-core-application .l-main-section @@ -96,11 +96,11 @@ a#create-angular-app +makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked - Now, build and run the application, you will find that .NET Core MVC application works but the Angular app does not. Open the the developer's tool in the browser, go to the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. + Now build and run the application. The .NET Core MVC application works but the Angular app appears not to work! Let's find out why. Open the developer tools in the browser and inspect the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. #### 404 Errors - These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. But we have an `app` folder and a `node_modules` folder in the root directory, why the browser can not find it? + These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. We have `app` folder and `node_modules` folders in the root directory, but why can't the browser find them? It is because .NET Core only exposes the `wwwroot` folder to browsers. All other contents in the project are private by default. It is by design so that you know exactly which part of the project is public. If the app asks for `/app` in a request, .NET Core looks for a physical `app` folder in the `wwwroot` folder. From 40c3c2d09d40ca009a2c3cd54194bec6e9345e4a Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Tue, 22 Nov 2016 10:45:05 +0000 Subject: [PATCH 21/23] Update code snippets for gulp-tslint. --- .../angular-in-dotnet-core/ts/app/app-routing.module.ts | 2 +- .../_examples/angular-in-dotnet-core/ts/app/app.component.ts | 2 +- .../docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts | 2 +- public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts index 6ba3ba0cad..4d42725ecd 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts @@ -71,4 +71,4 @@ export class AppRoutingModule {} Copyright 2016 Google Inc. All Rights Reserved. Use of this source code is governed by an MIT-style license that can be found in the LICENSE file at http://angular.io/license -*/ \ No newline at end of file +*/ diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts index 966139d7e7..63485dcbfe 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts @@ -4,4 +4,4 @@ import { Component } from '@angular/core'; selector: 'my-app', template: '<h1>Hello Angular!</h1>' }) -export class AppComponent { } \ No newline at end of file +export class AppComponent { } diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts index ba15af61a9..46adea2829 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts @@ -7,4 +7,4 @@ import { AppComponent } from './app.component'; declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) -export class AppModule { } \ No newline at end of file +export class AppModule { } diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts b/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts index b4b8cec553..77330a4a9f 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts +++ b/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts @@ -2,4 +2,4 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app.module'; const platform = platformBrowserDynamic(); -platform.bootstrapModule(AppModule); \ No newline at end of file +platform.bootstrapModule(AppModule); From b734514ac0d49935a947a5028cac24fe1c9bb0c0 Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Tue, 22 Nov 2016 12:41:39 +0000 Subject: [PATCH 22/23] Add instructions for .NET Core CLI audiences. --- .../cookbook/angular-in-dotnet-core.jade | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 40bf25a646..34207e0600 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -30,6 +30,11 @@ a#prerequisite 1. [TypeScript 2 for Visual Studio 2015](http://download.microsoft.com/download/6/D/8/6D8381B0-03C1-4BD2-AE65-30FF0A4C62DA/TS2.0.3-TS-release20-nightly-20160921.1/TypeScript_Dev14Full.exe) 1. [Node.js Tools for Visual Studio 2015](https://visualstudiogallery.msdn.microsoft.com/68faf8ac-b953-42f5-a908-55555deccf7a/file/206630/5/NTVS%201.2%20VS%202015.msi) (optional) +:marked +.l-sub-section + :marked + If you do not use Visual Studio, follow the [official instructions](https://www.microsoft.com/net/core) and install .NET Core. + a#create-dotnet-core-application .l-main-section :marked @@ -44,6 +49,17 @@ a#create-dotnet-core-application 1. Select `Web Application` and click OK. 1. Wait for Visual Studio to restore packages. +:marked +.l-sub-section + :marked + You can create a .NET Core Web Application using .NET Core CLI: + 1. Create a new folder + 1. Open a command line window: + + * `cd` into the new folder and run `dotnet new -t web` + * Run `dotnet restore` to restore packages + * Run `dotnet run` to start the web application at `localhost:5000` + a#create-angular-app .l-main-section :marked @@ -63,6 +79,14 @@ a#create-angular-app :marked When `package.json` is created, Visual Studio will automatically install all specified npm packages. You can also right click the `package.json` file and select `Restore Packages`. +:marked +.l-sub-section + :marked + If you do not use Visual Studio, open a command line window: + 1. `cd` to the root directory + 1. Run `npm i` to install npm packages + +:marked ### Create your Angular app Create an `app` folder in the root directory. @@ -98,6 +122,14 @@ a#create-angular-app :marked Now build and run the application. The .NET Core MVC application works but the Angular app appears not to work! Let's find out why. Open the developer tools in the browser and inspect the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. +:marked +.l-sub-section + :marked + If you do not use Visual Studio: + 1. Open a command line window, `cd` into the root directory and run `npm run tsc:w` to compile and watch TypeScript files + 1. Open another command line window, `cd` into the root directory and run `dotnet run` to start the web application at `localhost:5000` + +:marked #### 404 Errors These 404 errors indicate that the browser could not find files in `app` and `node_modules` folders. We have `app` folder and `node_modules` folders in the root directory, but why can't the browser find them? From b95f5d71d670a5d6ea701422f34ea1a9db3e2fbc Mon Sep 17 00:00:00 2001 From: Rex YE <rexebin@gmail.com> Date: Wed, 23 Nov 2016 10:17:20 +0000 Subject: [PATCH 23/23] Rename example folder with cb prefix. Use shell stylings for terminal commands. --- .../ts/_layout.html | 6 +- .../ts/app/app-routing.module.ts | 0 .../ts/app/app.component.ts | 0 .../ts/app/app.module.ts | 0 .../ts/app/main.ts | 0 .../ts/app/systemjs.config.ts | 0 .../ts/index.html | 0 .../ts/lib.html | 0 .../ts/nav.html | 0 .../ts/package1.json | 0 .../ts/startup.ts | 0 .../ts/styles.html | 0 .../ts/tsconfig1.json | 0 .../cookbook/angular-in-dotnet-core.jade | 80 +++++++++++-------- 14 files changed, 50 insertions(+), 36 deletions(-) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/_layout.html (95%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/app/app-routing.module.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/app/app.component.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/app/app.module.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/app/main.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/app/systemjs.config.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/index.html (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/lib.html (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/nav.html (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/package1.json (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/startup.ts (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/styles.html (100%) rename public/docs/_examples/{angular-in-dotnet-core => cb-angular-in-dotnet-core}/ts/tsconfig1.json (100%) diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html b/public/docs/_examples/cb-angular-in-dotnet-core/ts/_layout.html similarity index 95% rename from public/docs/_examples/angular-in-dotnet-core/ts/_layout.html rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/_layout.html index daf3fb9745..060f1d4ac4 100644 --- a/public/docs/_examples/angular-in-dotnet-core/ts/_layout.html +++ b/public/docs/_examples/cb-angular-in-dotnet-core/ts/_layout.html @@ -4,7 +4,7 @@ <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>@ViewData["Title"] - AngularWithDotnetCore + @ViewData["Title"] - AngularInDotnetCore @@ -40,7 +40,7 @@ - AngularWithDotnetCore + AngularInDotnetCore diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app-routing.module.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/app/app-routing.module.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app-routing.module.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app.component.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/app/app.component.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app.component.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app.module.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/app/app.module.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/app/app.module.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/app/main.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/app/main.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/app/main.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/app/systemjs.config.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/app/systemjs.config.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/app/systemjs.config.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/index.html b/public/docs/_examples/cb-angular-in-dotnet-core/ts/index.html similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/index.html rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/index.html diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/lib.html b/public/docs/_examples/cb-angular-in-dotnet-core/ts/lib.html similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/lib.html rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/lib.html diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/nav.html b/public/docs/_examples/cb-angular-in-dotnet-core/ts/nav.html similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/nav.html rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/nav.html diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/package1.json b/public/docs/_examples/cb-angular-in-dotnet-core/ts/package1.json similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/package1.json rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/package1.json diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/startup.ts b/public/docs/_examples/cb-angular-in-dotnet-core/ts/startup.ts similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/startup.ts rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/startup.ts diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/styles.html b/public/docs/_examples/cb-angular-in-dotnet-core/ts/styles.html similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/styles.html rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/styles.html diff --git a/public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json b/public/docs/_examples/cb-angular-in-dotnet-core/ts/tsconfig1.json similarity index 100% rename from public/docs/_examples/angular-in-dotnet-core/ts/tsconfig1.json rename to public/docs/_examples/cb-angular-in-dotnet-core/ts/tsconfig1.json diff --git a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade index 34207e0600..7309d5a4f9 100644 --- a/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade +++ b/public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade @@ -33,7 +33,7 @@ a#prerequisite :marked .l-sub-section :marked - If you do not use Visual Studio, follow the [official instructions](https://www.microsoft.com/net/core) and install .NET Core. + If you don't use Visual Studio, follow the [official instructions](https://www.microsoft.com/net/core) and install .NET Core. a#create-dotnet-core-application .l-main-section @@ -45,20 +45,23 @@ a#create-dotnet-core-application 1. Select `File` | `New` | `Project` from the menu 1. In the `New Project` dialog, select `Templates` | `Visual C#` | `.NET Core` 1. Select `ASP.NET Core Web Application (.NET Core)` template. - 1. Enter a name (for example `AngularWithDotnetCore`) for the project and click OK. + 1. Enter a name (for example `AngularInDotnetCore`) for the project and click OK. 1. Select `Web Application` and click OK. 1. Wait for Visual Studio to restore packages. :marked .l-sub-section :marked - You can create a .NET Core Web Application using .NET Core CLI: - 1. Create a new folder - 1. Open a command line window: + You can create a .NET Core Web Application using .NET Core CLI without Visual Studio. - * `cd` into the new folder and run `dotnet new -t web` - * Run `dotnet restore` to restore packages - * Run `dotnet run` to start the web application at `localhost:5000` + Perform *create-and-launch* steps with the these terminal commands: + + code-example(language="sh" class="code-shell"). + mkdir angularInDotnetCore + cd angularInDotnetCore + dotnet new -t web + dotnet restore + dotnet run a#create-angular-app .l-main-section @@ -70,8 +73,8 @@ a#create-angular-app In the root directory, create the following `package.json` and `tsconfig.json` files: +makeTabs( - `angular-in-dotnet-core/ts/package1.json, - angular-in-dotnet-core/ts/tsconfig1.json`, + `cb-angular-in-dotnet-core/ts/package1.json, + cb-angular-in-dotnet-core/ts/tsconfig1.json`, null, `package.json, tsconfig.json` @@ -82,9 +85,11 @@ a#create-angular-app :marked .l-sub-section :marked - If you do not use Visual Studio, open a command line window: - 1. `cd` to the root directory - 1. Run `npm i` to install npm packages + If you don't use Visual Studio, install npm packages with these terminal commands: + + code-example(language="sh" class="code-shell"). + cd angularInDotnetCore + npm i :marked ### Create your Angular app @@ -94,10 +99,10 @@ a#create-angular-app Create the following files in the `app` folder: +makeTabs( - `angular-in-dotnet-core/ts/app/systemjs.config.ts, - angular-in-dotnet-core/ts/app/app.module.ts, - angular-in-dotnet-core/ts/app/app.component.ts, - angular-in-dotnet-core/ts/app/main.ts`, + `cb-angular-in-dotnet-core/ts/app/systemjs.config.ts, + cb-angular-in-dotnet-core/ts/app/app.module.ts, + cb-angular-in-dotnet-core/ts/app/app.component.ts, + cb-angular-in-dotnet-core/ts/app/main.ts`, null, `app/systemjs.config.js, app/app.module.ts, @@ -110,14 +115,14 @@ a#create-angular-app For a quick start, open `Views/shared/_layout.cshtml` and insert Angular app’s libraries and `systemjs.config.js` script into the `` section: -+makeExample('angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/lib.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked To bootstrap the Angular app, also insert `Loading…` above `@RenderBody()`. The result should look like this: -+makeExample('angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/_layout.html', null, 'Views/shared/_layout.cshtml')(format='.') :marked Now build and run the application. The .NET Core MVC application works but the Angular app appears not to work! Let's find out why. Open the developer tools in the browser and inspect the console tab, you will find that the browser is complaining that it cannot find any of the scripts we inserted to `Views/Shared/_layout.cshtml` above. @@ -125,9 +130,18 @@ a#create-angular-app :marked .l-sub-section :marked - If you do not use Visual Studio: - 1. Open a command line window, `cd` into the root directory and run `npm run tsc:w` to compile and watch TypeScript files - 1. Open another command line window, `cd` into the root directory and run `dotnet run` to start the web application at `localhost:5000` + If you don't use Visual Studio: + + Compile and watch TypeScript files with these terminal commands: + code-example(language="sh" class="code-shell"). + cd angularInDotnetCore + npm run tsc:w + + :marked + Start the web application at `localhost:5000` with these terminal commands in a new terminal: + code-example(language="sh" class="code-shell"). + cd angularInDotnetCore + dotnet run :marked #### 404 Errors @@ -148,12 +162,12 @@ a#create-angular-app Open your `startup.cs` file and insert the following code under the line `app.UseStaticFiles();`. -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'redirect', 'startup.cs')(format='.') :marked Remember to insert the following `using` statements to `startup.cs`: -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'redirect-using', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'redirect-using', 'startup.cs')(format='.') :marked With the above code in place, .NET Core will redirect all requests asking for resources in `/app` and `/node_modules` to the physical `app` and `node_modules` folders in the root project directory. @@ -201,7 +215,7 @@ a#move-app The content of `Views/App/Index.cshtml` should look like this: -+makeExample('angular-in-dotnet-core/ts/index.html', null, 'Views/App/Index.cshtml')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/index.html', null, 'Views/App/Index.cshtml')(format='.') :marked ### Add a navigation link @@ -209,7 +223,7 @@ a#move-app Open `Views/Shared/_layout.cshtml`, under `
  • Contact
  • `, insert: -+makeExample('angular-in-dotnet-core/ts/nav.html', null, 'Views/Shared/_layout.cshtml')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/nav.html', null, 'Views/Shared/_layout.cshtml')(format='.') :marked ### Build and run @@ -241,7 +255,7 @@ a#angular-app-with-routes To style your Angular app the same way as the live example, open `Views/Shared/_layout.cshtml` and insert the following `` tag next to the `` tag in the `<head>` section: -+makeExample('angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/styles.html', null, 'Views/Shared/_layout.cshtml')(format='.') :marked ### Set `base href` @@ -262,11 +276,11 @@ a#angular-app-with-routes Open `startup.cs` file, in `ConfigureServices` method, insert the following line above `service.AddMvc();`: -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls', 'startup.cs')(format='.') :marked Remember to insert the following `using` statement to `startup.cs`: -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'lowercaseurls-using', 'startup.cs')(format='.') :marked Now rebuild and run your application and you will find the above error goes away. However only `Heroes` and `login` links work as intended. The lazy loaded modules `Crisis Center` and `Admin` are broken. In the console tab, the browser reports: `GET http://localhost:55771/crisis-center/crisis-center.module 404 (Not Found)`. Note the absence of `/app/` in the path. @@ -274,7 +288,7 @@ a#angular-app-with-routes The problem is that Angular could not find the lazy loaded modules because their paths were wrong. Let's check out the `app-routing.module.ts` file in the `app` folder. You can see the following: -+makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/app/app-routing.module.ts', 'absolute', 'app/app-routing.module.ts')(format='.') :marked The above code shows that you have two lazy loaded modules: `crisis-center` and `admin`. Both modules are loaded using absolute paths with their `loadChildren` property value starting with `app/`. Why is Angular requesting `crisis-center.module` via ` http://localhost:55771/crisis-center/crisis-center.module` without `app` in the path? It is because you have set the `base href` to `/app/` previously. The Angular router automatically omit `app` in the path assuming that base path already contains `app` because of the `base href`. @@ -282,7 +296,7 @@ a#angular-app-with-routes To fix the issue, simply use relative path like this: -+makeExample('angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/app/app-routing.module.ts', 'relative', 'app/app-routing.module.ts')(format='.') :marked Now, build and run. You will see that the Angular app is running without errors, until you refresh the browser. @@ -292,14 +306,14 @@ a#angular-app-with-routes When .NET Core receives a request url, it tries to match with its route configuration. The current route configuration in the `startup.cs` file is as follow: -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'route-default', 'startup.cs')(format='.') :marked In this case, when .NET Core sees `/app/heroes` url, it will try to execute `AppController`'s `Heroes` action, which does not exist. In order to solve this problem, you can create a new route map and redirect all urls starting with `/app`(e.g. `/app/heroes`)to `/app`. Open `startup.cs` and change the route configuration to the following: -+makeExample('angular-in-dotnet-core/ts/startup.ts', 'route-new', 'startup.cs')(format='.') ++makeExample('cb-angular-in-dotnet-core/ts/startup.ts', 'route-new', 'startup.cs')(format='.') :marked Note the second `MapRoute`, it will ask .NET Core to execute `AppController`'s `Index` action for all urls starting with `/app`.