Search code examples
c#asp.net-mvcasp.net-mvc-4error-handlingelmah

Exception handling with Elmah installed in an ASP.NET MVC 4 Application


I have built up a nice MVC4 application, decided to secure it and all is fine. Below is the filter I use to help prevent XSS attacks as an example.

public class IsPostedFromThisSiteAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        //TODO: - Possible problems in future:
        //1. Is there a way to handle the execptions and just display a friendly error page / message.

        if (filterContext.HttpContext != null)
        {
            if (filterContext.HttpContext.Request.UrlReferrer == null)
                throw new System.Web.HttpException("Invalid Submission");

            //if (filterContext.HttpContext.Request.UrlReferrer.Host != "localhost/YeatsClinical.PatientPortal.Web")
            if (filterContext.HttpContext.Request.UrlReferrer.AbsolutePath != ConfigurationManager.AppSettings["SiteURL"])
                throw new System.Web.HttpException("This form was not submitted from this site!");
        }
    }
}

My MVC app has Elmah installed and it works great too.

The problem is, I know about the error above and I don't want to display an exception message, or log it or anything like that (all of which I can do easily). Instead I want to handle it properly by displaying a nice little message to my user. How can I change the code above to allow this to either display a view or partial view with a nice little message or just output some text somewhere to let the user know what went wrong in a nice way that doesn't cause the application to crash, perhaps in this particular case, returning him to the correct login screen.


Solution

  • Just assign the Result property on the filterContext:

    public class IsPostedFromThisSiteAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //TODO: - Possible problems in future:
            //1. Is there a way to handle the execptions and just display a friendly error page / message.
    
            if (filterContext.HttpContext != null)
            {
                if (filterContext.HttpContext.Request.UrlReferrer == null)
                {
                    var viewResult = new ViewResult
                    {
                        ViewName = "~/Views/Shared/Invalid.cshtml"
                    };
                    filterContext.Result = viewResult;
                    return;
                }
    
                if (filterContext.HttpContext.Request.UrlReferrer.AbsolutePath != ConfigurationManager.AppSettings["SiteURL"])
                {
                    var viewResult = new ViewResult
                    {
                        ViewName = "~/Views/Shared/InvalidSite.cshtml"
                    };
                    filterContext.Result = viewResult;
                    return;
                }
            }
        }
    }
    

    This will prevent the controller action to be executed and will immediately execute the ActionResult you have assigned to the Result property of the filterContext. Basically you are short-circuiting the execution of the action. You could return whatever ActionResult you want: ViewResult, PartialViewResult, JsonResult, RedirectToRouteResult, ...