Search code examples
c#controllerroutes.net-coreattributerouting

Attribute Routing not existing routes


I have a project with Attribute routing like:

[Route("home")]
public class HomeController : Controller
{
     [HttpPost]
     public IActionResult Post(int id)
     {
     }

     [HttpGet]
     public IActionResult Get()
     {
     }
}

Now I want to catch all Get/Post/Put Requests which doesn't have a specified route. So I can return an error, redirect to the home page and such stuff. Is it possible with AttributeRouting or should I use Conventional Routing in the startup? And how would the "not existing" route look there?


Solution

  • By default, server returns 404 HTTP Status code as the response for requests that are not handled by any middleware (attribute/convention routing is part of MVC middleware).

    In general, what you always can do is to add some middleware at the beginning of the pipeline to catch all responses with 404 status code and do custom logic or change response.

    In practice, you can use the existing mechanism provided by ASP.NET Core called StatusCodePagesmiddleware. You can register it directly as raw middleware by

    public void Configure(IApplicationBuilder app)  
    {
        app.UseStatusCodePages(async context =>
        {
            context.HttpContext.Response.ContentType = "text/plain";
            await context.HttpContext.Response.WriteAsync(
                "Status code page, status code: " + 
                context.HttpContext.Response.StatusCode);
        });
    
        //note that order of middlewares is importante 
        //and above should be registered as one of the first middleware and before app.UseMVC()
    

    The middleware supports several extension methods, like the following (the difference is well explained in this article):

    app.UseStatusCodePages("/error/{0}");
    app.UseStatusCodePagesWithRedirects("/error/{0}");
    app.UseStatusCodePagesWithReExecute("/error/{0}");
    

    where "/error/{0}" is a routing template that could be whatever you need and it's {0} parameter will represent the error code.

    For example to handle 404 errors you may add the following action

    [Route("error/404")]
    public IActionResult Error404()
    {
        // do here what you need
        // return custom API response / View;
    }
    

    or general action

    [Route("error/{code:int}")]
    public IActionResult Error(int code)