Angular .NET Core:http get 未命中控制器方法

问题描述 投票:0回答:1

我正在开发一个 Angular 应用程序,该应用程序使用 .NET Core 后端和 EF 来学习 Angular。该解决方案是通过在 Visual Studio 2022 中选择 Angular 和 ASP.NET Core 项目模板生成的。我的控制器是通过使用实体框架选择带有操作的 API 控制器选项来搭建的。

有两种型号。员工和工资。每个都有一个控制器。即EmployeesController 和SalariesController。有一个访问控制器的服务类。当用户单击第一页上的按钮时,将加载员工页面。这工作正常。用户可以单击每个员工旁边的链接来查看他们的工资。 “工资”页面的代码与“员工”页面的代码相同。但是当我单击链接时,页面加载时没有任何数据。当我调试控制器上的操作方法时,没有被击中。

这是我的员工控制器。

namespace EmployeesAngular.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class EmployeesController : ControllerBase
    { 
        private readonly EmployeesAngularServerContext _context;

        public EmployeesController(EmployeesAngularServerContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Employee>>> GetEmployee()
        {
            return await _context.Employee.ToListAsync();
        }
    }
}

这是工资控制器

namespace EmployeesAngular.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class SalariesController : ControllerBase
    {
        private readonly EmployeesAngularServerContext _context;

        public SalariesController(EmployeesAngularServerContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Salary>>> GetSalary()
        {
            return await _context.Salary.ToListAsync();
        }
    }
}

这是app.component.html 文件。

<div class="container">
  <h3 class="d-flex justify-content-center">Employee Details</h3>
  <nav class="navbar navbar-expand-sm bg-light navbar-dark">
    <ul class="navbar-nav">
      <li class="nav-item">
        <button routerLink="employees" class="m-1 btn btn-light btn-outline-primary" Button>Employees</button>
      </li>
    </ul>
  </nav>
  <router-outlet></router-outlet>
</div>

这是employees.component.html 文件。

<table class="table table-striped">
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Department</th>
      <th>Date Of Joining</th>
      <th>Total Salary</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let dataItem of EmployeeList">
      <td>{{dataItem.firstName}}</td>
      <td>{{dataItem.lastName}}</td>
      <td>{{dataItem.department}}</td>
      <td>{{dataItem.joinDate}}</td>
      <td>{{dataItem.totalSalary}}</td>
      <td><a routerLink="/salaries" routerLinkActive="active" ariaCurrentWhenActive="page">View Salary Components</a></td>
      <td><a routerLink="/editEmployee" routerLinkActive="active" ariaCurrentWhenActive="page">Edit</a></td>
    </tr>
  </tbody>
</table>

这是 salaries.component.html 文件的代码。

<table class="table table-striped">
  <thead>
    <tr>
      <th>Basic</th>
      <th>Allowance</th>
      <th>Bonus</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let dataItem of SalaryList">
      <td>{{dataItem.basic}}</td>
      <td>{{dataItem.allowance}}</td>
      <td>{{dataItem.bonus}}</td>
    </tr>
  </tbody>
</table>

这是employees.component.ts 文件。

import { Component, OnInit } from '@angular/core';
import { ApiserviceService } from '../apiservice.service';

@Component({
  selector: 'app-employees',
  templateUrl: './employees.component.html',
  styleUrls: ['./employees.component.css']
 })
export class EmployeesComponent implements OnInit {

  constructor(private service: ApiserviceService) { }

  EmployeeList: any = [];

  ngOnInit(): void {
    this.refreshEmpList();
  }

  refreshEmpList() {
    this.service.getEmployeeList().subscribe(data => {
      this.EmployeeList = data;
    });
  }
}

这是 salaries.component.ts 文件。

import { Component, OnInit } from '@angular/core';
import { ApiserviceService } from '../apiservice.service';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-salaries',
  templateUrl: './salaries.component.html',
  styleUrl: './salaries.component.css'
})
export class SalariesComponent implements OnInit {
  constructor(private service: ApiserviceService) {
}

  SalaryList: any = [];

  ngOnInit(): void {
    this.refreshSalary();
  }

  refreshSalary() {
    this.service.getSalaryList().subscribe(data => {
      this.SalaryList = data;
    });
  }
}

这是我的服务,称为 apiservice。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
 
export class ApiserviceService {
  constructor(private http: HttpClient) { }

  getEmployeeList(): Observable<any[]> {
    return this.http.get<any[]>('employees');
  }

  getSalaryList(): Observable<any[]> {
    return this.http.get<any[]>('salaries');
  }
}

这就是 app-routing-module.ts 文件中路由的完成方式。

const routes: Routes = [
  { path: 'employees', component: EmployeesComponent },
  { path: 'salaries', component: SalariesComponent },
  { path: 'editEmployee', component: EditEmployeeComponent },
];

当我单击薪资链接并观察浏览器中开发人员工具下的控制台时,我看到一条错误消息

语法错误:意外的标记'<', "

我搜索了此错误并尝试实施建议的修复。正如本页中提到的,我将代码修改为如下所示。

getSalaryList(): Observable<any[]> {
  return this.http.get<any[]>('salaries', { responseType: 'text' });
}

这给了我一个编译器错误,说

类型“Observable”不可分配给类型“Observable

在responseType属性中也这么说

没有与此调用匹配的重载

按照此页面中的建议我尝试像这样更改Index.html页面中的基本href,但这也不起作用。

<base href="/">

to

<base href=".">

根据另一个答案,我修改了服务类中的代码,如下所示。

getSalaryList(): Observable<any[]> {
    const httpOptions: Object = {
      headers: new HttpHeaders({
        'Accept': 'text/html',
        'Content-Type': 'text/plain; charset=utf-8'
      }),
      responseType: 'text'
    };

    return this.http.get<any[]>('salaries', httpOptions);
}

这也不会影响控制器操作方法。并在浏览器控制台中给我一个错误,说

NG0900:尝试比较时出错...仅允许数组和可迭代对象。

我查看了类似问题的其他几个答案。但回应似乎并不完整。大多数问题没有选定的答案,并且对答案的建议似乎不适用于此问题。所以我发布这个问题。

虽然我尝试了各种建议,因为它们是在答案中给出的,但我很困惑为什么代码不适用于薪资,而适用于员工。

非常感谢您的帮助。

c# angular entity-framework .net-core
1个回答
0
投票

有什么问题吗?

当你写下这行代码时,你的 Angular 和 asp.net 正在不同的端口上运行

this.http.get<any[]>('employees');

您的请求将尝试让员工通过 Angular 端口

https://localhost:4200/employees
,Angular 会将其解决为
EmployeesComponent
,而不是调用后端

解决问题

首先,让我们区分 API 和组件。通过更改控制器中的以下行,使您的 API 在

/api/Employees
api/salaries
上运行

Route("api/[controller]")]

其次,我们需要告诉 Angular 任何路线都以

/api/**
开头,将其转发到后端,这将在客户端文件夹中名为
porxy.conf.js
的文件中完成,删除
weatherForecast
并添加
/api/**

const PROXY_CONFIG = [
  {
    context: [
      "/api/**"
    ],
    target,
    secure: false
  }
]

最后,更改您的服务以使用正确的路线

export class ApiserviceService {
    constructor(private http: HttpClient) { }

  getEmployeeList(): Observable<any[]> {
    console.log("inside the methode..")
    return this.http.get<any[]>('/api/Employees');
  }

  getSalaryList(): Observable<any[]> {
    return this.http.get<any[]>('/api/salaries');
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.