Display custom error page and show exception details - asp.net-mvc

I have a custom Errors controller that looks like this:
public class ErrorsController : BaseController
{
public ActionResult RaiseError(string error = null)
{
string msg = error ?? "An error has been thrown (intentionally).";
throw new Exception(msg);
}
public ActionResult Error404()
{
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult Error500()
{
Response.TrySkipIisCustomErrors = true;
var model = new Models.Errors.Error500()
{
ServerException = Server.GetLastError(),
HTTPStatusCode = Response.StatusCode
};
return View(model);
}
}
My Errors500.cshtml looks like this:
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Error500</title>
</head>
<body>
<div>
An internal error has occurred.
#if (Model != null && Model.ServerException != null && HttpContext.Current.IsDebuggingEnabled)
{
<div>
<p>
<b>Exception:</b> #Model.ServerException.Message<br />
</p>
<div style="overflow:scroll">
<pre>
#Model.ServerException.StackTrace
</pre>
</div>
</div>
}
</div>
</body>
</html>
and my web.config has my error handlers specified as such:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace" >
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/Errors/Error404" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" subStatusCode="-1" responseMode="ExecuteURL" path="/Errors/Error500" />
</httpErrors>
The problem is: everytime I call /errors/raiseerror to test my 500 handling; I'm redirected to errors/error500 (fine). However, the exception data isn't rendered on the page because the Server.GetLastError() call returns null instead of the exception thrown by RaiseError().
What's the best way to handle a custom 500 error page where that custom page can render out the exception details as well?

The easiest way to go about this is:
Use MVC's built-in support to handle Exceptions. By default MVC uses HandleErrorAttribute that is registered in App_Start\FilterConfig.cs:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
Now make sure you have a view called Error in Views\Shared folder. The view by default has model of type HandleErrorInfo with a property named Exception. You can show the Exception message and other details if you want like this:
Error.cshtml
#model HandleErrorInfo
#if(Model != null)
{
#Model.Exception.Message
}
You can customize the Error.cshtml page the way you want...

Related

Custom Error pages in MVC ASP NET for all errors

i want in my app to have custom error pages for 401, 404 etc error codes.
I try this but doesn't work?
In Web.config
<customErrors mode="Off" /> //Under system.web
<httpErrors errorMode="Custom" existingResponse="Replace" >//Under system.webServer
<clear />
<remove statusCode="401"/>
<error statusCode="401" responseMode="ExecuteURL" path="/Error/Unauthorized" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error" />
</httpErrors>
I have create also Error controller and Unauthorized views.
How can this work?
Example:
web.config:
in system.web add
<customErrors mode="RemoteOnly" defaultRedirect="~/error">//RemoteOnly means that on local network you will see real errors
<error statusCode="401" path="~/Error/Unauthorized" />
<error statusCode="404" path="~/Error/NotFound" />
<error statusCode="500" path="~/Error" />
</customErrors>
in system.webServer add
<httpErrors errorMode="Detailed" />
Controller:
your controller something like
public class ErrorController : Controller
{
public ViewResult Index()
{
return View("Error");
}
public ViewResult NotFound()
{
Response.StatusCode = 404;
return View("NotFound");
}
}
View:
and your view something like
#model System.Web.Mvc.HandleErrorInfo
#{
Layout = "_Layout.cshtml";
ViewBag.Title = "Error";
}
<div class="list-header clearfix">
<span>Error</span>
</div>
<div class="list-sfs-holder">
<div class="alert alert-error">
An unexpected error has occurred. Please contact the system administrator.
</div>
#if (Model != null && HttpContext.Current.IsDebuggingEnabled)
{
<div>
<p>
<b>Exception:</b> #Model.Exception.Message<br />
<b>Controller:</b> #Model.ControllerName<br />
<b>Action:</b> #Model.ActionName
</p>
</div>
}
</div>
Hopefully it's help for you.

ASP MVC Redirecting to error page

I'm trying to handle eventual errors in my view, by using the HandleError attribute on my view:
The reason why the Action is called 'Error' is because it gets a list of logged errors from a database.
[HandleError]
public ActionResult Error(int? page)
{
var errors = errorRepository.GetErrors();
// stuff for paging
var pageSize = 10;
var pageNumber = (page ?? 1); // if there is no page, return page 1
return View("Error", errors.ToPagedList(pageNumber, pageSize));
}
This is the error page in the /Shared/ folder:
#model System.Web.Mvc.HandleErrorInfo
#{
ViewBag.Title = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
But for some reason, the error page is never being shown, even though I've forced an exception in the action method. It just goes to the default url in my RouteConfig file.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Any hint as to why it doesn't show my error page is greatly appreciated!
I am sorry I have to add this as answer, but I don't have enough points to comment.
To be able to help you I need to see the code within the HandleErrorAttribute. However what you normally want to do in these cases is:
1) Add a config setting in the web.config to say that you will handle the exceptions on your own. Something like:
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error statusCode="500" redirect="~/Error/InternalServer" />
<error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
</system.web>
2) Add the methods to accept those incoming calls in the ErrorController (In this case Index(), InternalServer(), NotFound())
3) Get the logs from your database and display them to the user than

Configuring Magical Unicorn Mvc Error Toolkit

I am trying to configure the Magical Unicorn Mvc Error Toolkit (v 2.1.2) on my MVC4 web site but I can't get it to work. Here's my code:
Web.config
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Error/ServerError">
<error statusCode="404" redirect="~/Views/Error/NotFound.cshtml" />
</customErrors>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="~/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="500" path="~/Error/ServerError" responseMode="ExecuteURL" />
</httpErrors>
<system.webServer>
Error Controller
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return View();
}
}
[These were based on this https://stackoverflow.com/a/7499406/236860 post]
CustomerErrorHandler.cs (App_Start)
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using WorldDomination.Web.Mvc;
using CustomErrors.App_Start;
[assembly: WebActivator.PreApplicationStartMethod(typeof(CustomErrorHander), "PreStart")]
namespace CustomErrors.App_Start
{
public static class CustomErrorHander
{
public static void PreStart()
{
// Register the custom error handling module.
DynamicModuleUtility.RegisterModule(typeof (CustomErrorHandlingModule));
}
}
}
I am testing this application in Visual Studio 2012 using IIS Express. If I try to navigate to a non-existent page, or go to an action method that calls an exception I either get the default browser error page or a blank page.
I have also modified the above code as suggested at ASP.NET MVC Custom Error Pages with Magical Unicorn but this dis not seem to make any difference.
Can anyone point me in the right direction to get this working.
In the end, I could not get the Magical Unicorn Mvc Error Toolkit to work. The good news is that I don't think I had to! Since I am deploying the MVC application to an IIS 7.5 web server, I could use the later system.webServer.httpErrors section of my Web.config and a custom error controller.
Web.Config
<system.web>
<httpRuntime targetFramework="4.5" />
<compilation debug="false" targetFramework="4.5">
<customErrors mode="Off" /> <!-- IMPORTANT -->
...
</system.web>
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="403" />
<error statusCode="403" responseMode="ExecuteURL" path="/Error/AccessDenied" />
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
<remove statusCode="500" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error/ApplicationError" />
</httpErrors>
...
</system.webServer>
Error Controller
public class ErrorController : Controller
{
public ActionResult AccessDenied()
{
Response.StatusCode = (int)HttpStatusCode.Forbidden;
Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
// return Json friendly response here
}
return View();
}
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
// return Json friendly response here
}
return View();
}
public ActionResult ApplicationError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.TrySkipIisCustomErrors = true;
if (Request.IsAjaxRequest())
{
// return Json friendly response here
}
return View();
}
}
This all seems to work well with IIS Express and IIS 7.5.
Elmah logs the errors without any changes to the default error filters.
Fiddler also suggests that the correct HTTP Status codes are also being correctly maintained.

MVC error page is loaded in partial view

I have a error page with layout that works fine in most cases but when there is an error in a controller that returns a partial view the error page and its layout is placed in the partial view. I guess thats logical but I want the error page to be loaded as full page. How do I accomplish that without changing all error handling.
web.config:
<customErrors mode="On" defaultRedirect="~/Error">
<error statusCode="500" redirect="~/SystemPages/ErrorPage" />
<error statusCode="403" redirect="~/SystemPages/FileNotFound" />
<error statusCode="404" redirect="~/SystemPages/FileNotFound" />
</customErrors>
Global.asax:
Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
filters.Add(New HandleErrorAttribute())
End Sub
BaseController:
Protected Overrides Sub OnException(ByVal filterContext As ExceptionContext)
If filterContext Is Nothing Then Return
If TypeOf (filterContext.Exception) Is FaultException Then
Dim CodeName As String =
CType(filterContext.Exception, FaultException).Code.Name
Dim Message As String = CType(filterContext.Exception, FaultException).Message
TempData("ErrorMessage") = Message
Else
Logging.LogDebugData(HamtaDebugInformation(filterContext.RouteData))
Logging.WriteExceptionLog(filterContext.Exception)
TempData("ErrorMessage") = filterContext.Exception.Message
End If
Response.Redirect("/SystemPages/ErrorPage")
End Sub
SearchController:
Function GetData() As ActionResult
...
Return PartialView("_Tab", vmData)
ErrorPage:
#Code
ViewData("Title") = "ErrorPage"
Layout = "~/Views/Shared/_Layout.vbhtml"
End Code
<div id="mainContent" class="oneColumn">
<div class="panel">
<span class="panelTLC"></span>
<span class="panelTRC"></span>
<div id="inputPanel" class="panelContent">
<div class="modul">
<div class="modulHead">
<span class="TLC"></span>
<span class="TRC"></span>
</div>
<div class="modulContent">
<span class="TLC"></span><span class="TRC"></span>
<p>#ViewBag.ErrorMessage</p>
<p>#TempData("ErrorMessage")</p>
<span class="BLC"></span>
<span class="BRC"></span>
</div>
</div>
</div>
<span class="panelBLC"></span><span class="panelBRC"></span>
</div>
</div>
You could just use a try catch block and in the catch return a View() instead of PartialView().
Function GetData() As ActionResult
Try
...
Return PartialView("_Tab", vmData)
Catch ex as Exception
//Handle exception here ( send to error log, etc)
Return View("~/SystemPages/ErrorPage")
End Try
OR
web.config:
<customErrors mode="On"/>
BaseController:
Protected Overrides Sub OnException(ByVal filterContext As ExceptionContext)
If filterContext Is Nothing Then Return
Dim Message As String
If TypeOf (filterContext.Exception) Is FaultException Then
Dim CodeName As String =
CType(filterContext.Exception, FaultException).Code.Name
Message = CType(filterContext.Exception, FaultException).Message
Else
Logging.LogDebugData(HamtaDebugInformation(filterContext.RouteData))
Logging.WriteExceptionLog(filterContext.Exception)
Message = filterContext.Exception.Message
End If
Response.Redirect(String.Format("~/Error/HttpError/?message={1}", "HttpError", Message))
End Sub
ErrorController:
public class ErrorController : Controller
{
// GET: /Error/HttpError
public ActionResult HttpError(string message) {
return View("ErrorTest", message);
}
This post: ASP.NET MVC Custom Error Handling Application_Error Global.asax?
goes into how to handle each type of error separately. Keep in mind you are handling your exceptions in basecontroller instead of the global.asax file. Which if you were able to change your exception handling, that would be the better way to do it.

how to handle this in mvc 3 and iis 6 like stackoverflow?

how to handle 400 bad request like stackoverflow in mvc 3 , iis 6 ?
eg: www.stackoverflow.com/a<
return 404 not found page , instead of a YSOD page
updated: why this does not work ?
<httpErrors errorMode="Detailed">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" subStatusCode="-1" path="/notfound" responseMode="ExecuteURL" />
<error statusCode="400" subStatusCode="-1" path="/Error" responseMode="ExecuteURL" />
</httpErrors>
Use customErrors tag of web.config:
<customErrors mode="On" defaultRedirect="UrlToRedirect" >
<error statusCode="400" redirect="UrlToRedirect"/>
</customErrors>
Eg.:
<customErrors mode="On" defaultRedirect="~/Error/Index">
<error statusCode="400" redirect="~/Error/Index"/>
</customErrors>
if UrlToRedirect = "~/Error/Index", Here, in this url, "Error" is the name of controller & "Index" is the name of Action method which returns Error View Page.
public class ErrorController : Controller
{
public ActionResult Index()
{
return View("Error");
}
}
In the "\Views\Shared Folder" of you application, you have "Error.cshtml" view page.

Resources