Reputation: 531
I'm using UseStatusCodePagesWithReExecute in my .NET Core 2.1 web app as follows
app.UseStatusCodePagesWithReExecute("/Error/{0}");
and in my Controller I point to 1 of 2 views, a 404.cshtml view and a generic error.cshtml view
public class ErrorController : Controller
{
[HttpGet("[controller]/{statusCode:int}")]
public IActionResult Error(int? statusCode = null)
{
if (statusCode.HasValue)
{
if (statusCode == (int)HttpStatusCode.NotFound)
{
return View(statusCode.ToString());
}
}
return View();
}
}
Now in my page controller I can do the following and it works as expected. It will show error.cshtml
public IActionResult SomePage()
{
return BadRequest();
}
Now if I change the above to the following, my ErrorController does get hit but by the time it does a blank view showing just "Some details" has been loaded in the browser.
public IActionResult SomePage()
{
return BadRequest("Some details");
}
Any ideas why? I want it to load error.cshtml
Upvotes: 1
Views: 2535
Reputation: 27538
As @Kirk Larkin said , UseStatusCodePagesWithReExecute middleware won't work and it will only handle the status code .
You can use Result filters to write your custom logic to filter that and return a ViewResult :
public class StatusCodeResultFilter : IAsyncResultFilter
{
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
// retrieve a typed controller, so we can reuse its data
if (context.Controller is Controller controller)
{
// intercept the NotFoundObjectResult
if (context.Result is BadRequestObjectResult badRequestObject)
{
// set the model, or other view data
controller.ViewData.Model = badRequestObject.Value;
// replace the result by a view result
context.Result = new ViewResult()
{
StatusCode = 400,
ViewName = "Views/Error/status400.cshtml",
ViewData = controller.ViewData,
TempData = controller.TempData,
};
}
}
await next();
}
}
Register the filter :
services.AddMvc(config =>
{
config.Filters.Add(new StatusCodeResultFilter());
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
In your view , you can directly get the detail message by :
@Model
Reference : https://stackoverflow.com/a/51800917/5751404
Upvotes: 1