在ASPNET核心SPA Angular应用程序中返回404状态代码 [英] Return 404 status code in aspnet core SPA Angular application

查看:174
本文介绍了在ASPNET核心SPA Angular应用程序中返回404状态代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个用于dotnet核心的Angular SPA项目模板的项目(在VS2017和dotnet core 2.0中可用).

I am working on a project using the Angular SPA project template for dotnet core (the one available in VS2017 and dotnet core 2.0).

我有一个Angular组件,如果用户转到无效的URL,它会显示未找到"消息.

I have an Angular component to display a "Not Found" message if a user goes to an invalid URL.

我还启用了服务器端预渲染.从服务器返回预渲染的未找到"页面时,如何使它返回404的HTTP状态代码?

I also have server-side pre-rendering enabled. When returning the prerendered "Not Found" page from the server, how would I make it return an HTTP status code of 404?

我发现执行此操作的每种方法都使用Express作为后端Web服务器,但我无法在aspnet核心后端上找到任何用于执行此操作的资源.

Every method I have found to do this uses Express as the backend webserver, I have not been able to find any resources for doing this on an aspnet core backend.

感谢您的帮助!

为清楚起见进行

我不希望针对特定的MVC控制器操作或应用程序错误返回404.

I am not looking to return a 404 for a specific MVC controller action or on an application error.

我希望从特定的Angular2/4组件返回404,并在服务器端由

I am looking to return a 404 from a specific Angular2/4 component, rendered server-side by Microsoft.AspNetCore.SpaServices.

为了进行比较,此处是使用以下解决方案的示例NodeJS上的Express Web服务器和用于服务器端渲染的angular Universal.

For comparison, here is an example of a solution using the Express web server on NodeJS and angular universal for server-side rendering.

推荐答案

我找到了解决方案.

首先,我们需要创建一个可注入服务,组件可以使用该服务来设置状态代码:

First, we need to create an injectable service that components can use to set the status code:

import { Injectable } from '@angular/core';

@Injectable()
export class HttpStatusCodeService {

  private statusCode: number;

  constructor(){
    this.statusCode = 200;
  }

  public setStatusCode(statusCode: number) {
    this.statusCode = statusCode;
  }

  public getStatusCode(): number {
    return this.statusCode;
  }
}

我们将需要将此服务添加到主AppModule模块中的providers阵列中:

We will need to add this service to the providers array in the main AppModule module:

...
providers: [
    ...
    HttpStatusCodeService,
    ...
]
...

然后我们需要在我们的boot.server.ts文件中添加两行(加上import语句)(请注意,这是基于VS2017模板创建的库存文件):

And then we need to add two lines (plus the import statement) within our boot.server.ts file (note this is based on the stock file created by the VS2017 template):

import 'reflect-metadata';
import 'zone.js';
import 'rxjs/add/operator/first';
import { APP_BASE_HREF } from '@angular/common';
import { enableProdMode, ApplicationRef, NgZone, ValueProvider } from '@angular/core';
import { platformDynamicServer, PlatformState, INITIAL_CONFIG } from '@angular/platform-server';
import { createServerRenderer, RenderResult } from 'aspnet-prerendering';
import { AppModule } from './app/app.module.server';

//ADD THIS LINE
import { HttpStatusCodeService } from './path/to/services/http-status-code.service';

enableProdMode();

export default createServerRenderer(params => {
    const providers = [
        { provide: INITIAL_CONFIG, useValue: { document: '<app></app>', url: params.url } },
        { provide: APP_BASE_HREF, useValue: params.baseUrl },
        { provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
    ];

    return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
        const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
        const state = moduleRef.injector.get(PlatformState);
        const zone = moduleRef.injector.get(NgZone);

        //ADD THIS LINE: this will get the instance of the HttpStatusCodeService created for this request.
        const statusCodeService = moduleRef.injector.get(HttpStatusCodeService); 

        return new Promise<RenderResult>((resolve, reject) => {
            zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
            appRef.isStable.first(isStable => isStable).subscribe(() => {
                // Because 'onStable' fires before 'onError', we have to delay slightly before
                // completing the request in case there's an error to report
                setImmediate(() => {
                    resolve({
                        html: state.renderToString(),

                        //ADD THIS LINE: this will get the currently set status code and return it along with the prerendered html string
                        statusCode: statusCodeService.getStatusCode() 
                    });
                    moduleRef.destroy();
                });
            });
        });
    });
});

最后,我们需要在任何不返回HTTP 200的组件中设置状态代码:

And then finally we need to set the status code in any component that shouldn't return HTTP 200:

import { Component } from '@angular/core';

import { HttpStatusCodeService } from './path/to/services/http-status-code.service';

@Component({
    selector: 'not-found',
    templateUrl: './not-found.html'
})
export class NotFoundComponent {

  constructor(private httpStatusCodeService: HttpStatusCodeService) {
    httpStatusCodeService.setStatusCode(404);
  }
}

这篇关于在ASPNET核心SPA Angular应用程序中返回404状态代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆