简体   繁体   中英

ASP.NET Core Razor Pages OnGet of Error model not being executed

I modified the default Error.cshtml.cs to log when an error gets thrown, and it worked for a while. Now after updating to .NET Core 3.0 release it's no longer working.

Here is my ErrorModel:

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
    public string RequestId { get; set; }

    public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

    public IActionResult OnGet()
    {
        RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;

        var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

        try
        {
            Logger.LogMessage(new LogMessage
            {
                RequestId = RequestId,
                Exception = exceptionHandlerPathFeature?.Error,
                Time = DateTime.Now
            });
        }
        catch (Exception)
        {
            // ignored
        }

        return Page();
    }
}

And here is my Error cshtml:

@page "/Error"
@model ErrorModel
@{
    ViewData["Title"] = "Error";
}
<h2 class="text-danger">Ein Fehler ist aufgetreten.</h2>

@if (Model.ShowRequestId)
{
    <p>
        <strong>Anfrage ID:</strong> <code>@Model.RequestId</code>
    </p>
}

<h3>Hoppla, das sollte nicht passieren</h3>
<p>
    Bitte merken Sie sich doch den Ablauf der zu diesem Fehler führte und melden Sie ihn dem 
    verantwortlichen Entwickler somit er behoben werden kann. Bitte fügen Sie auch mindestens die ersten 8 Zeichen der Anfrage ID an
</p>

For reference here is my Configure Method in my Startup class

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();
    app.UseSession();

    if (env.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseCookiePolicy();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
        endpoints.MapHub<FingerprintHub>("/Hub/FingerprintHub");
        endpoints.MapHub<RegistrationHub>("/Hub/RegistrationHub");
    });

    app.UseWebSockets();
}

The problem is that my ShowRequestId is always false, meaning my RequestId is null or empty. I put a breakpoint in my OnGet method and confirmed it's not being executed.

I also tried using a Middelware to log my Exceptions, but that didn't work either.

Anybody have an idea what could be causing this?

I think your error is produced in a POST, PUT or DELETE, and you are trying to controlate it in the OnGet method of ErrorModel, this is executed only for errors produced in GET operations

Hope this helps!!!

There are 2 reasons that app.UseExceptionHandler("/Error") stopped working for many of errors.

  1. ExceptionHandler could invoke Error page either by GET method or POST method, POST method will be called when you POST a request to server and exception occurred.

  2. When POST method is invoked from ExceptionHandler, it can't reach the Error page if you don't add the [IgnoreAntiforgeryToken] to PageModel .

So you have to add OnPost method and attribute [IgnoreAntiforgeryToken] .

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
    ...

    public ActionResult OnGet()
    {
        HandleError();
        return Page();
    }

    public ActionResult OnPost()
    {
        HandleError();
        return Page();
    }

    private void HandleError()
    {
        ...
        var exceptionHandlerPathFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
        ....
    }
}

Enjoy it!

You could try to use middleware like below:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        //if (env.IsDevelopment())
        //{
        //    app.UseDeveloperExceptionPage();
        //}
        //else
        //{
        //    app.UseExceptionHandler("/Error");
        //    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        //    app.UseHsts();
        //}

        app.Use(async (Context, next) =>
        {
            try
            {
                await next();
            }
            catch (Exception e)
            {
                Context.Response.Redirect("/Error");
            }
        });

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
        });
    }

If you want to show the error pages of the HTTP Status codes, you could call the UseStatusCodePages method before request handling middleware (for example, Static File Middleware and MVC Middleware) in the Configuremethod of the Startup class.

Reference:

https://www.learnrazorpages.com/configuration/custom-errors

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-2.2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM