Reputation: 836
I'm looking for a way to handle all null reference exceptions in an asp.net application, and do an action if they are encountered, for example redirect to an error page. I have tried putting something in global.asax but it doesnt seem to work. So my question is that for example if I have a code like this that throws an exception when there is no argument:
public ActionResult GeneratePDFforSignature(int? id)
{
Signature signature = db.SignatureDatabase.Find(id);
return View();
}
How can I catch the exception application wide and stop my application from crashing. I have read up a bit on this matter and added some code to my global.asax, but it doesnt handle the null reference exceptions.
This is what I added to my Global.asax. I found it in another thread (ASP.NET MVC 5 error handling):
protected void Application_Error()
{
HttpContext httpContext = HttpContext.Current;
if (httpContext != null)
{
RequestContext requestContext = ((MvcHandler)httpContext.CurrentHandler).RequestContext;
/* when the request is ajax the system can automatically handle a mistake with a JSON response. then overwrites the default response */
if (requestContext.HttpContext.Request.IsAjaxRequest())
{
httpContext.Response.Clear();
string controllerName = requestContext.RouteData.GetRequiredString("controller");
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
IController controller = factory.CreateController(requestContext, controllerName);
ControllerContext controllerContext = new ControllerContext(requestContext, (ControllerBase)controller);
JsonResult jsonResult = new JsonResult();
jsonResult.Data = new { success = false, serverError = "500" };
jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
jsonResult.ExecuteResult(controllerContext);
httpContext.Response.End();
}
else
{
httpContext.Response.Redirect(Server.MapPath("~/Shared/Error.cshtml"));
}
}
How can I catch all null reference exceptions, if it is possible? I am aware that I could fix my example code that throws this exception by adding a
if (id == null){//code}
but my program is rather large and I am hoping for a solution that will catch everything so I don't have to copy and paste a snippet of code to catch exceptions between different controllers 400 times. How can I catch all null reference exceptions and redirect to an error page in asp.net mvc 5?
Upvotes: 0
Views: 828
Reputation: 52270
Rather than catching all null reference exceptions, I suggest you prevent them from happening to begin with, by revising your routing table.
I'm guessing you have a route that looks something like this:
{action}/{id?}
The problem is, id, apparently, is not really optional. So the route should be this instead (no question mark):
{action}/{id}
Then, you will need an additional route to catch any HTTP request that doesn't match any route definitions (including GeneratePDFforSignature with no ID). You can append this to the end of your routing definitions, like this (as an example):
routes.MapRoute(
name= "CatchAll",
url="{*any}",
defaults = new {controller = "Error", action = "Handler"}
)
Your controller and action names may be different, but you get the idea.
Upvotes: 1
Reputation: 134
//use this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace nullReference_Exception.Models
{
public class CustomException : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception.InnerException == null)
{
if (!filterContext.ExceptionHandled && filterContext.Exception is Exception)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Error" },
{ "controller", "Home" }
});
filterContext.ExceptionHandled = true;
}
}
}
}
}
//at controller
using nullReference_Exception.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace nullReference_Exception.Controllers
{
[CustomException] //on every controller
public class HomeController : Controller
{
public ActionResult Index()
{
LoginViewModel aLog=null;
var a=aLog.Email;
return View();
}
//you don't need to declare this on every controller
public ActionResult Error()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
}
// now make a error action and view
//read comment carefully
Upvotes: 1