VsCode  W poprzednim wpisie dokonaliśmy fuzji aplikacji ASP.NET Core z Angular. Stworzyliśmy hybrydę aplikacji MVC  z SPA Angular. Jak podobny proces wyglądałby, gdybyśmy jednak chcieli do tego użyć Visual Studio Code.

Tym razem przy pomocy ASP.NET Core 2 stworzę aplikację REST, która zwróci mi listę gier. Angular pobierze te dane z usługi i wyświetli je na stronie.

Nie będę korzystał z gotowego szablonu ASP.NET Core 2 z Angular. Stworzymy wszystko od podstaw.

Otwórz więc Visual Studio Code i wybierz folder, w którym chcesz popracować na tą fuzją.

WebFusion Folder

Praca z Visual Studio Code, jeśli chodzi o pliki JavaScript  TypeScript jest dużo przyjemniejsza niż w Visual Studio 2017. Co więcej, Visual Studio Code rozumie, że większość pracy we współczesnych framework-ach odbywa się w konsoli. Visual Studio Code może więc dla Ciebie okazać się lepszą alternatywą do pracy niż Visual Studio 2017.

Visual Studio Code ma wbudowany terminal. Uruchom go więc.

Integreted terminal

Do naszego folderu chcemy utworzyć kolejny folder z aplikacją Angular.

ng new AngularFolder

Proces pobierania paczek jest długi więc wykaż się cierpliwością.

ng new

O ile Internet nie padł wszystko powinno pójść jak po maśle.

Pobieranie paczek zakończone sukcesem

Teraz w konsoli przejdź do folder AngularFolder.

CD ANGULARFOlder

Sprawdźmy czy wszystko jest ok.

npm start

Uruchamiając polecenie NPM Start, które wywołuje polecenie ng serve kompilujemy kod TypseScript oraz uruchamiamy serwer Node.js z adresem Localhost:4200

NPM START

Na tym etapie nie powinno być żadnych komplikacji.

Angular 5

Zmodyfikujmy lekko kod.

app.component.ts

W pliku app.component.html dodajmy prostą listę elementów

<h1><span style="color:#C40030">WebFusion of ASP.NET CORE 2 and Angular 5</span></h1>

<ul>
  <li *ngFor="let item of games">
    {{item}}
  </li>
</ul>

A w app.component.ts dodajmy definicję tablicy elementów gier, która ma być wyświetlona na tej stronie.

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  games: string[];
  constructor()  {
    this.games = [];
    this.games.push('Mortal Kombat 2');
    this.games.push('Dune 2');
    console.log(this.games);
  }
}

Angular automatycznie powinien się prze kompilować i wyświetlić listę gier.

WebFusion of ASP.NET Core 2 and Angular 5

Teraz czas na utworzenie aplikacji ASP.NET Core. W terminalu utwórz kolejną instancję linii poleceń i do dzieła.

New Terminal

3 :ASP.NET Core

Visual Studio Code nie ma wizualnego kreatora, ale .NET Core oferuje nam także swoje polecenia, dzięki którym możemy utworzyć aplikację Web API.

dotNET new webApi

Visual Studio Code wykryje aplikację .NET i będzie chciał utworzyć pliki konfiguracyjne służące do budowy aplikacji, jak i jej debugowania.

KOMUNIKAT visual studio code

Pliki te będą folderze .vscode.

vscode launch.json

W kontrolerze ValueController wywal domyślny kod i wstaw prostą metodę GET, która zwróci nam krótką listę gier.

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]  
    public IEnumerable<string> Get()  
    {  
        return new string[] 
        {  
            "Cannon Fodder", 
            "Shadow of the Beast" 
        };  
    }  
}

.NET automatycznie nie przebudowuje aplikacji po każdej edycji jak Angular dlatego musisz zrobić to sam poleceniem.

dotnet build

Powinno się obejść bez błędów.

Kompilacja powiodła się

Teraz poleceniem…

dotnet run

Uruchamiasz serwer IIS Express pod adresem localhost:5000 i tam możesz sprawdzić czy twój kontroler rzeczywiście zwraca listę gier.

api values

Teraz co trzeba zrobić aby nasze dwie aplikację gadały do siebie.

4: Dwie aplikacje gadają do siebie localhost:5000 z 4200

Po pierwsze musimy dokonać paru kluczowych zmian w naszej aplikacji Angular. Po pierwsze potrzebujemy usługi, która wykonałaby zapytanie do naszej usługi ASP.NET Core.  Utwórz więc plik app.service.ts

app.service.ts

Oto jej kod.

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import 'rxjs/add/operator/map';
@Injectable()
export class AppService{
    constructor(private http: Http) {

    }
    getGames(){
        const apiUrl = 'http://localhost:5000/api/values';
        return this.http.get(apiUrl)
                   .map((res: Response) => {
                     return res.json();
        });
    }
}

Usługa korzysta z  modułu HTTP trzeba więc go dodać w app.module.ts. Sam serwis AppService, który przed chwilą utworzyliśmy też.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {HttpModule} from '@angular/http';
import { AppService } from './app.service';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule
  ],
  providers: [AppService],
  bootstrap: [AppComponent]
})
export class AppModule { }

W pliku AppComponent dodajemy odwołanie do naszego serwisu i teraz tablica gier zostanie uzupełniona.

import { Component } from '@angular/core';
import { AppService } from './app.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  games: string[];
  constructor(private appService: AppService)
  {
    this.games = [];
    this.populateGames();
  }

  populateGames()
  {
      this.appService.getGames().subscribe(res => {
        this.games = res;
      });
  }
}

Normalnie odpytanie usługi z innego portu by nie przeszło w wyniku konfliktu domen CORS. 

Dlatego trzeba dodać zezwolenie. W pliku startup.cs dodaje więc te linijki kodu.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseCors(builder => builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());   
        app.UseMvc();
}

Aplikacja Angular powinna się przekompilować sama. Aplikację .NET musimy przekompilować my.

dotnet build

dotnet run

Twoim oczom powinna się ukazać lista gier pobrana z ASP.NET Core 2.

image

Dwa serwer i dwa adres to jednak problem. Dlatego zróbmy tę samą sztuczkę co w poprzednim wpisie.

6 : Jeden adres

Z edytuj dwa pliki .angular-cli.json oraz tsconfig.json.

.angular-cli.json

W pliku .angular-cli.json zmień właściwość „outDir” na „../wwwroot/”.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "angular-folder"
  },
  "apps": [
    {
      "root": "src",
      "outDir": "../wwwroot/",

Analogicznie zrób to w pliku .tsconfig.json.

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "../wwwroot/",

W pliku startup.cs musimy też dodać obsługę plików statystycznych.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    app.UseStaticFiles();
    app.UseCors(builder => builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());   
        app.UseMvc();
}

Przebuduj aplikację Angular tak aby utworzyły się skompilowane pliki JavaScript w folderze wwwroot.

ng-build

ng-build

wwwroot

Przebuduj też aplikację .NET i ją uruchom.

dotnet build
dotnet run

Teraz pod adresem localhost:5000 w serwerze IIS możesz oglądać fuzję aplikacji ASP.NET Core i Angular.

localhost:5000

To wszystko.