我正在开发一个 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:尝试比较时出错...仅允许数组和可迭代对象。
我查看了类似问题的其他几个答案。但回应似乎并不完整。大多数问题没有选定的答案,并且对答案的建议似乎不适用于此问题。所以我发布这个问题。
虽然我尝试了各种建议,因为它们是在答案中给出的,但我很困惑为什么代码不适用于薪资,而适用于员工。
非常感谢您的帮助。
当你写下这行代码时,你的 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');
}
}