Reputation: 37780
There is custom error page:
public sealed class ErrorModel : PageModel
{
public ErrorModel()
{
// app stops at breakpoint inside ctor
}
public IActionResult OnGet()
{
// app doesn't stop here, why?
// this is for debugging purposes only
return BadRequest();
}
}
and its view:
@page
@model ErrorModel
@if (Model != null)
{
<p>
The error page.
</p>
}
Page is registered in usual way:
app.UseExceptionHandler("/Error");
When application redirects to error page, it stops on breakpoints inside page constructor and page view, but ignores code inside OnGet
. Since app doesn't call my OnGet
, page renders without any useful data I fill inside OnGet
.
All breakpoints are enabled - I'm debugging actual code.
Any idea what's happening and how to solve this?
UPD
I've reduced the page model code and the view. When app stops at this line:
@if (Model != null)
the call stack is:
Portal.App.Views.dll!Portal.Pages.Pages_Error.ExecuteAsync() Line 4 C# Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.RazorPageAdapter.ExecuteAsync() Unknown Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext context) Unknown Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(Microsoft.AspNetCore.Mvc.Razor.IRazorPage page, Microsoft.AspNetCore.Mvc.Rendering.ViewContext context, bool invokeViewStarts) Unknown Microsoft.AspNetCore.Mvc.Razor.dll!Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext context) Unknown Microsoft.AspNetCore.Mvc.ViewFeatures.dll!Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.Rendering.ViewContext viewContext, string contentType, int? statusCode) Unknown Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageContext pageContext, Microsoft.AspNetCore.Mvc.RazorPages.PageResult result) Unknown Microsoft.AspNetCore.Mvc.RazorPages.dll!Microsoft.AspNetCore.Mvc.RazorPages.PageResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) Unknown
So, app executes PageResult
. Where this result comes from?
UPD 2
This looks like authentication issue. When user is authenticated, everything works as expected. But for non-authenticated users my OnGet
isn't called. ErrorModel
hasn't Authorize
attribute. How authentication affects this?
I've no any custom authentication config, so, I assume defaults are used:
private void ConfigureMvcServices(IServiceCollection services)
{
services
.AddMvc()
// another services;
}
Error page is in the Pages
folder - Pages/Error
.
Besides, if user is not authenticated, and page requires authentication, 401 must be returned, isn't it?
Upvotes: 1
Views: 1730
Reputation: 37780
I've figured it out. The pitfall is here:
To configure a custom error handling page for the Production environment, use the Exception Handling Middleware. The middleware:
- Catches and logs exceptions.
- Re-executes the request in an alternate pipeline for the page or controller indicated. The request isn't re-executed if the response has started.
"Re-executes" means, literally, that if exception was raised in GET handler, middleware calls error page's OnGet. If it was raised in POST handler, middleware calls OnPost, etc:
public class ErrorModel : PageModel
{
public ErrorModel()
{
}
public void OnGet()
{
// This executes when exception was in OnGet
}
public void OnPost()
{
// This executes when exception was in OnPost
}
// ...
}
In my case there was a GET request on page with authentication, and POST one on non-authenticated page, so here's the difference in behavior.
Upvotes: 4
Reputation: 91
Have you enabled custom errors in the web config. Like this:
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear />
<error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>
Upvotes: 0