Вызовите веб-API-контроллер с помощью Angular 2

Я новичок в Angular2. Я хочу вызвать API с помощью Angular2 в моем проекте MVC6. Я пробовал много вещей (включая руководство по Angular2, вызывающего веб-интерфейс ASP.NET) без успеха.

Я не знаю, с чего начать, или какие файлы нужны.

Ответ 1

Я бы посмотрел на некоторые из примеров на Github, чтобы узнать, как это сделали другие люди. Есть целый ряд вещей, которые должны быть в порядке, чтобы все это работало, и ошибки могут быть туманными, пока вы не начнете работать.

Добавьте в проект класс контроллера веб-API. Чтобы убедиться, что все работает сначала, я бы предложил жесткую кодировку вашего атрибута HttpGet для "api/values".

ValuesController.cs.:

    public class ValuesController : Controller
    {
      [HttpGet("api/values")]
      public IActionResult Get()
      {
          return new JsonResult(new string[] { "value1", "value2" });
      }

Startup.Cs. Вам нужны маршруты angular2, чтобы не мешать маршрутам ASP.NET. Это означает, что вам нужно обслуживать index.html клиенту, если есть ошибка 404. Приложение app.Use лямбда выполняет это. Обратите внимание, что перед вызовами app.UseDefaultFiles() и app.UseStaticFiles()

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        ...
        var angularRoutes = new[] {
             "/home"
         };

        app.Use(async (context, next) =>
        {
            if (context.Request.Path.HasValue && null != angularRoutes.FirstOrDefault(
                (ar) => context.Request.Path.Value.StartsWith(ar, StringComparison.OrdinalIgnoreCase)))
            {
                context.Request.Path = new PathString("/");
            }
            await next();
        });

        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

Как только вы установили эту настройку, вы должны протестировать свой API с помощью Postman, чтобы убедиться, что маршрутизация работает так, как вы этого хотите. Если это не сработает, оно не будет работать в Angular. У меня http://localhost:5001/ установлен как мой URL-адрес приложения в настройках отладки проекта Visual Studio.

postman

Если это работает правильно, перейдите к загрузке с помощью Angular 2. Вам нужно будет использовать базовый элемент сразу после заголовка в вашем html файле. Это сообщает маршрутизатору Angular, что статическая часть URL-адреса:

Index.html

    <base href="/">

Затем вам нужно создать службу в angular2, чтобы получить значения из вашего API: dataService.ts

import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map'
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../app.constants';

@Injectable()
export class DataService { 
  private actionUrl: string;
  constructor(private _http: Http, private _configuration: Configuration) {
    this.actionUrl = 'http://localhost:5001/api/values/';
}

public GetAll = (): Observable<any> => {
    return this._http.get(this.actionUrl)
        .map((response: Response) => <any>response.json())
        .do(x => console.log(x));
}

Оператор .do в RxJS очень удобен. Это позволит вам отлаживать то, что вы правильно получаете значения из своего API. Подробнее см. блог Андре Стальца.

Наконец, создайте компонент для использования службы: app.component.ts

import { Observable } from 'rxjs/Observable';
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { DataService } from '../services/DataService';

@Component({
    selector: 'app',
    template: `My Values: <ul><li *ngFor="let value of values">
        <span>{{value.id}} </span>
      </li></ul>`,
    providers: [DataService]
})

export class AppComponent implements OnInit {
  public values: any[];
  constructor(private _dataService: DataService) {}
  ngOnInit() {
    this._dataService
        .GetAll()
        .subscribe(data => this.values = data,
        error => console.log(error),
        () => console.log('Get all complete'));
  }
}

Ответ 2

Вот как я это сделал (angular2 как интерфейс с ядром веб-API) -

  • Создайте контроллер, используя инфраструктуру сущности, которая предоставляет все действия - GET, POST, PUT и DELETE. Обратитесь к этой ссылке, если вы новичок в веб-интерфейсе api и entity - https://docs.efproject.net/en/latest/platforms/aspnetcore/existing-db.html

  • Включено CORS в веб-API

[Это делается для обработки перекрестной связи с localhost: 3000 (angular2) на localhost: 59024 (webapi)]

Сначала добавьте зависимость в project.json - "Microsoft.AspNetCore.Cors": "1.0.0",

затем включите CORS в startup.cs, как это, -

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

Вы можете найти более подробную информацию о CORS здесь - https://docs.asp.net/en/latest/security/cors.html

3.In Angular2 front-end, вы можете написать свой сервисный компонент следующим образом:

@Injectable()
export class WebApiService {

    private _webApiUrl = 'http://localhost:59024/api/EmployeeMastersAPI'; 

        constructor(private _http: Http) { 

        }

    getEmployees(): Observable<{}> {
        return this._http.get(this._webApiUrl)
            .map((response: Response) => <any[]> response.json())
             .do(data => console.log('All: ' +  JSON.stringify(data)))
             .catch(this.handleError)
            ;
    }

    getEmployee(id: number): Observable<IEmployee> {
        return this.getEmployees()
            .map((emp: IEmployee[]) => emp.find(p => p.EMPID === id));
    }

    addEmployeesDetails(emp) {
        var headers = new Headers();
        headers.append('Content-Type', 'application/json; charset=utf-8');
        console.log('add emp : ' +  JSON.stringify(emp));
        this._http.post(this._webApiUrl, JSON.stringify(emp), { headers: headers }).subscribe();

    }

    private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }

}

Посмотрите, поможет ли это.