Reputation: 2695
in my web.config blow you can see redirectMode="ResponseRewrite". I read this is what I need to preserve the status code. Unfortunately as soon as I have it in, I get:
"An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated."
Omitting this variable successfully redirects me to ~/Error/Index.cshtml but has a response of 200. doh. Any direction would be hugely appreciated, thanks.
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error/Index">
<error statusCode="404" redirect="~/Error/Index"/>
<error statusCode="500" redirect="~/Error/Index"/>
</customErrors>
<httpRuntime targetFramework="4.5" />
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
<remove statusCode="403"/>
<remove statusCode="404"/>
<remove statusCode="500"/>
<error statusCode="403" path="~/Error/Index" responseMode="File"/>
<error statusCode="404" path="~/Error/Index" responseMode="File"/>
<error statusCode="500" path="~/Error/Index" responseMode="File"/>
</httpErrors>
</system.webServer>
In my filterconfig.cs:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// does this conflict?
filters.Add(new HandleErrorAttribute());
}
}
Upvotes: 6
Views: 2240
Reputation: 860
Cannot remember where I saw this code, or what I changed, but it works fine in my MVC web app
Web.config
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
<customErrors mode="Off" />
</system.web>
Global.aspx
protected void Application_EndRequest(Object sender, EventArgs e)
{
ErrorConfig.Handle(Context);
}
ErrorConfig.cs
namespace Web.UI.Models.Errors
{
public static class ErrorConfig
{
public static void Handle(HttpContext context)
{
switch (context.Response.StatusCode)
{
case 401:
Show(context, 401);
break;
case 404:
Show(context, 404);
break;
case 500:
Show(context, 500);
break;
}
}
//TODO uncomment 500 error
static void Show(HttpContext context, Int32 code)
{
context.Response.Clear();
var w = new HttpContextWrapper(context);
var c = new ErrorController() as IController;
var rd = new RouteData();
rd.Values["controller"] = "Error";
rd.Values["action"] = "Index";
rd.Values["id"] = code.ToString(CultureInfo.InvariantCulture);
c.Execute(new RequestContext(w, rd));
}
}
}
ErrorController
public class ErrorController : Controller
{
// GET: Error
[HttpGet]
public ViewResult Index(Int32? id)
{
var statusCode = id.HasValue ? id.Value : 500;
var error = new HandleErrorInfo(new Exception("An exception with error " + statusCode + " occurred!"), "Error", "Index");
int errorCode = statusCode;
ViewBag.error = errorCode;
return View("Error");
}
}
ErrorsViewModel
namespace Web.UI.Models.Errors
{
public class ErrorViewModel
{
public string DisplayErrorMessage { get; set; }
public string DisplayErrorPageTitle { get; set; }
}
}
Then in shared folder error page add
@model Web.UI.Models.Errors.ErrorViewModel
@{
int errorCode = Convert.ToInt32(@ViewBag.error);
switch (errorCode)
{
case 404:
ViewBag.Title = "404 Page Not Found";
Html.RenderPartial("~/Views/Shared/ErrorPages/HttpError404.cshtml");
break;
case 500:
ViewBag.Title = "Error Occurred";
Html.RenderPartial("~/Views/Shared/_Error.cshtml");
break;
default:
ViewBag.Title = @Model.DisplayErrorPageTitle;
Html.RenderPartial("~/Views/Shared/ErrorPages/HttpNoResultsFound.cshtml");
break;
}
}
The above returns 404 status for page not found and 500 for error, hope it helps
Upvotes: 1