Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
further review.
  • Loading branch information
rexebin committed Nov 21, 2016
commit a6469a7473025c14cea1ca02b8114938f0e231b0
44 changes: 22 additions & 22 deletions public/docs/ts/latest/cookbook/angular-in-dotnet-core.jade
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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='.')

Expand All @@ -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?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have app and node_modules folders, 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'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.

Expand All @@ -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

Expand All @@ -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`:

Expand Down Expand Up @@ -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.

Expand All @@ -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.

Expand All @@ -214,37 +214,37 @@ 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

.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.

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
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 `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

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 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.

Expand All @@ -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.

Expand Down