6

I have a simple .NET Core 2.0 project. Here is the Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment environment)
{
  app.UseStatusCodePagesWithReExecute("/error/{0}.html");

  app.UseStaticFiles();

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

When I enter an invalid url, /error/404.html is displayed as expected, but the browser gets a 200 status code, instead of the expected 404 status.

What am I doing wrong? Can I not use a static html file as error page?

Bjarte Aune Olsen
  • 3,230
  • 4
  • 24
  • 36
  • UseStaticFiles is likely setting the 200 when it serves the 404.html. you could override it in the event on the options. – Tratcher Sep 23 '17 at 05:56

1 Answers1

9

When you use app.UseStatusCodePagesWithReExecuteyou

Adds a StatusCodePages middleware that specifies that the response body should be generated by re-executing the request pipeline using alternate path.

As path /error/404.html exists and works OK, the 200 status is used.


You may use the following approach (look into this article for more detailed explanation):

setup action that will return View based on a status code, passed as a query parameter

public class ErrorController : Controller  
{
    [HttpGet("/error")]
    public IActionResult Error(int? statusCode = null)
    {
        if (statusCode.HasValue)
        {
            // here is the trick
            this.HttpContext.Response.StatusCode = statusCode.Value;
        }

        //return a static file. 
        return File("~/error/${statusCode}.html", "text/html");

        // or return View 
        // return View(<view name based on statusCode>);
    }
}

then register middleware as

app.UseStatusCodePagesWithReExecute("/Error", "?statusCode={0}");

this placeholder {0} will be replaced with the status code integer automatically during redirect.

Set
  • 47,577
  • 22
  • 132
  • 150
  • Thanks, this answer helped me a bit further. But is it possible to redirect from ErrorController to my static 404.html? – Bjarte Aune Olsen Sep 23 '17 at 17:41
  • If it was unclear in my original question, "error" is a directory in "wwwroot", not a controller, and "404.html" is an html file in the wwwroot/error directory. – Bjarte Aune Olsen Sep 23 '17 at 17:46
  • @BjarteAuneOlsen: have edited answer so the action now returns a static file instead of view (look into https://github.com/aspnet/Mvc/issues/3751). You don't need to use redirect, as you again will see 200 OK => redirect works in the following way: the server sends a 302 code along with a Location header, and the browser requests the new URI specified by the Location header instead. – Set Sep 23 '17 at 17:52
  • The method File(string filepath) doesn't seem to exist in dotnet core, so I'll go back to using a view like you suggest in your first answer. – Bjarte Aune Olsen Sep 24 '17 at 07:05
  • @BjarteAuneOlsen right, there is now a [ControllerBase.File(string virtualPath, string contentType)](https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc.Core/ControllerBase.cs#L1231) method. Just specify "text/html" as a content type. – Set Sep 24 '17 at 08:24
  • Thanks, I'll check it out. – Bjarte Aune Olsen Sep 25 '17 at 08:50