I am new to MVC and am working on error handling and exceptions. As you may or may not know, the implementation of handling HTTP errors through Views is outright clunky for the following reasons:
1.) The page status code is set to 200, which will result in the error page being indexed by a search engine and letting the user know that everything went OK, which is not true.
2.) The URL of the error page changes, which I do not want. Unfortunately, I cannot use ResponseRewrite with a View because it uses Server.Transfer under the hood, which means it looks for a file as opposed to a View.
I prefer to use a View for all application exception and HTTP error handling because the View maintains the site layout by calling _Layout.cshtml in the View startup. So, after working on this for the past week, I think I found an implementation that allows me to use a View while addressing the two issues that I mentioned above (see Solution 1 by Starain Chen in the weblink below).
My problem is this, for me the View is being displayed in all text. Any ideas why this is happening, and more importantly, how to force the site to be rendered as opposed to being dumped out as text?
https://forums.asp.net/t/1996026.aspx?How+to+keep+url+same+after+page+postback+with+error+in+MVC
My code:
web.config (truncated)
<system.web>
<customErrors mode="On" >
</customErrors>
</system.web>
<system.webServer>
<modules>
<remove name="FormsAuthentication" />
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
</system.webServer>
Global.asax
namespace WebApplication1
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_Error()
{
if (Context.IsCustomErrorEnabled)
ShowError(Server.GetLastError());
}
private void ShowError(Exception exception)
{
var httpException = exception as HttpException ?? new HttpException(500, "Internal Server Error", exception);
Response.Clear();
var routeData = new RouteData();
routeData.Values.Add("Controller", "Error");
routeData.Values.Add("fromAppErrorEvent", true);
routeData.Values.Add("ErrorMessage", httpException.Message);
routeData.Values.Add("httpStatusCode", httpException.GetHttpCode());
switch (httpException.GetHttpCode())
{
case 403:
routeData.Values.Add("action", "HttpError403");
break;
case 404:
routeData.Values.Add("action", "HttpError404");
break;
case 500:
routeData.Values.Add("action", "HttpError500");
break;
default:
routeData.Values.Add("action", "GeneralError");
break;
}
Server.ClearError();
IController controller = new Controllers.ErrorController();
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
}
}
ErrorController
namespace WebApplication1.Controllers
{
public class ErrorController : Controller
{
// GET: Error
public ActionResult HttpError404()
{
ViewBag.errormessage = this.RouteData.Values["ErrorMessage"];
ViewBag.status = this.RouteData.Values["httpStatusCode"];
Response.StatusCode = Convert.ToInt32(this.RouteData.Values["httpStatusCode"]);
Response.TrySkipIisCustomErrors = true;
return View();
}
}
}
HttpError404.cshtml View
@{
ViewBag.Title = "HttpError404";
}
@*<h2>HttpError404</h2>
ErrorMessge: @ViewBag.errormessage
<br />
Status: @ViewBag.status*@