locked
Handle 400 status code using UseStatusCodePagesWithReExecute middleware RRS feed

  • Question

  • User-158191824 posted

    Using ASP.NET Core 3.1 - MVC, I need to redirect a 400 error to a special page ( It occurs when a signed-out user tries to sign out again). But for simplicity I just want to render status code number to the user in here, these are my codes :

     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();             
                }
                else
                {
                    app.UseExceptionHandler("/Error");             
                    app.UseHsts();
                    app.UseStatusCodePagesWithReExecute("/statusError/{0}");
                    app.Use((context, next) =>     //did nothing
                    {
                        context.SetEndpoint(null);
                        return next();
                    });
                }
    
                app.UseHttpsRedirection();
                app.UseStaticFiles(new StaticFileOptions
                {
                    OnPrepareResponse = ctx =>
                    {
                        const int durationInSeconds = 3600;                     
                        ctx.Context.Response.Headers[HeaderNames.CacheControl] =
                            "public,max-age=" + durationInSeconds;
                    }
                });
                app.UseRouting();
                app.UseAuthentication();
                app.UseAuthorization();
                app.UseSession();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{area=User}/{controller=Home}/{action=Index}/{id?}");
                });
    
            }

    and this is my error action method:

            [IgnoreAntiforgeryToken]   //did nothing
            [Route("statusError/{statusCode}")]
            public IActionResult statusError(int statusCode)
            {      
                return RedirectToAction("Message", "Home", new { message = statusCode.ToString() });
            }	

    This is the problem : when I type `https://localhost:44330/foo/bar` , I get "Error number is : 404", when I type `https://localhost:44330/login` I get "Error number is : 405", but in case of 400 error (when user is signed out and try to sign out again in another browser tab) , I again get "Error number is : 404" but I expect 400 number and I can't manage it.


    I read somewhere it was a bug but I do not know how to fix it.
    Additional information: when a 405 or 404  statusCode passed to the statusError action method, it steps forward as expected  and everything is ok, but in case of 400 , at first, statusError action method retrieve 400 and the code steps forward but it backs again to the statusError action method with 404 parameter again. I do not know why in case of 400 it comes back to the statusError action method again with a new value of 404 !! I can't understand why in case of 400 , the error action method shpuld be met twice ?!

    Tuesday, November 24, 2020 7:00 AM

All replies

  • User-158191824 posted

    Adding  [IgnoreAntiforgeryToken] to my LogOut action method was the answer. When user in tab1 sign out, the token changes, and when the user in tab2 again tries to sign out, the old token was sent to action method and I got 400 status code error... 

    I still do not know the sequence of operation, but apparently non-matching token was the reason why middle ware can't handle 400 error in my case ! 

    Tuesday, November 24, 2020 10:35 AM
  • User1312693872 posted

    Hi,ehsan_kabiri_33

    Have you solved your problem, can add [IgnoreAntiforgeryToken] help? You should mark the helpful answer, including yours. That will make it

    easier for other users to view.

    And to check the sequence of operation, you can add break point to the related lines and check the trace.

    Best Regards,

    Jerry Cai

    Tuesday, December 1, 2020 2:40 AM
  • User-158191824 posted

    Thanks for replying "Jerry Cai". As I said in the second post of mine, I added [IgnoreAntiforgeryToken] to my LogOut action method, so the user never gets error on status code 400 when tries to sign-out while he is signed-out in the next tab of browser. In fact I did not solve the problem, just cleared the problem !! 

    I know using of break point thanks for mentioning. 

    Any way this solved my logout problem but I still have the main question : 

    When 405 status code occurs, 405 sent to statuserror action method and my method  renders 405 to the client .

    But when 400 status code occurs ( in case of invalid AntiforgeryToken for example) , 400 sent to status error action method , with input parameter as 400, I followed the process step by step pressing F10 button, it goes to line "return Content(statusCode.ToString());" and ready to out of the status error method, but when reaches to  the end brace, it turns back to the statuserror action method with statusCode = 404 :( !! without going to any other line . 

    (In case of 400, I used many break points in startUp.cs, Repositories, ApplicationDbContext, Dispose and any where you think ! The code goes any where !!  )

    The problem is that I wanted to separate errors shown to the client in case of url=www.mywebsite.com/Foo/Bar which should be 404 of course and the case of trying to log out more than once, but in both cases I have to render one message (Not found) and it is my problem that still exists.

    This is my last try:

    [Route("statusError/{statusCode}")]
    public IActionResult HttpStatusCodeHandler(int statusCode)
      {
                if (statusCode == 400)
                {
                    return Content(400.ToString());
                }
                return Content(statusCode.ToString());
      }

    But in case of 400 it still returns 404 !! 

    Tuesday, December 1, 2020 6:38 AM