调用 .NET Core 中缺少的端点会产生 404,但也可以作为对 Angular 的响应

Call to a missing endpoint in .NET Core produces 404 but also OK as response to Angular

调用我的后端时,我忘记了我们更改了端点的名称,所以我得到了 404。但是,我注意到提供的文本不是 Not Found在这种情况下是预期的,而是 OK。如图所示,错误消息中的(正确的)状态代码与(错误的)状态名称之间缺乏关联。

起初,我怀疑后端使用了类似这样的东西忘记正确分类响应的状态码。然后,我意识到这是不可能的,因为端点不存在,所以内容不可能是由于在那里执行的任何事情。

//[HttpGet("coordinates/{id}")]
[HttpGet("coords/{id}")]
public async Task<ActionResult> GetCoordinates(int id)
{
  ...
  // if (output == null)
  //  return NotFound(id);


  return Ok(output);
}

我需要诊断问题的帮助,目前我不确定是后端需要触摸还是 Angular 中发生的事情。联系服务器的代码,书上写的很直接

getCoordinates(id: number): Observable<boolean> {
  return this.http
  .get<boolean>(this.url + "coordinates/" + id);
}

Observable 然后像这样在组件中使用(布尔值在 GET 上可能令人惊讶,但在我正在处理的实际情况下它是有意义的)。

onSave() {
  this.service.getCoordinates(this.id)
    .subscribe(
      suc => this.router.navigate([this.origin]),
      err => console.log(err));
}

错误处理响应的可能点在哪里?或者是,在某种程度上,我不知道某种好的状态?我没有足够的把握在这里做出判断。

我只找到了 this,它只是证实了我的直觉,有些东西有问题,但没有提供关于什么的提示。另外,它是 PHP,所以我不确定相关性。

根据 RFC 7540 documentation,

For HTTP/2 responses, a single ":status" pseudo-header field is
defined that carries the HTTP status code field (see [RFC7231],
Section 6). This pseudo-header field MUST be included in all
responses; otherwise, the response is malformed (Section 8.1.2.6).

HTTP/2 does not define a way to carry the version or reason phrase
that is included in an HTTP/1.1 status line.

这里有一个相同的讨论:https://github.com/whatwg/fetch/issues/599#issue-255768557

The Fetch spec simply defines statusText as the status message value, which unless otherwise specified is OK.

For HTTP/2 it seems status message could be interpreted any number of ways:

  • empty string - because there is no reason phrase "OK"
  • because that is always the default (would be weird to have a 404 OK though) implementation defined
  • such as some default reason text for a status code

statusText:'OK' 符合 RFC,see here

然而,可以使用中间件 (as shown here) 在 .NET 核心 WebAPI 中自定义您的响应。

这是我们应用程序中自定义错误处理的示例

Startup.cs

public class Startup
{
    public void Configure(
        IApplicationBuilder app,
        IHostingEnvironment env,
        IApiVersionDescriptionProvider provider,
        VersionedODataModelBuilder builder)
    {
        app.UseMiddleware<ErrorHandling>();

ErrorHandling.cs

public class ErrorHandling
{
    public ErrorHandling(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        // Error handling code here
        // For example if you want to set a specific statusCode
        context.Response.StatusCode = MySpecificStatusCode;