Custom Errors in ASP.Net MVC: It couldn't be simpler, right?
secretGeek .:dot Nuts about dot Net:.
home .: about .: sign up .: sitemap .: secretGeek RSS

Custom Errors in ASP.Net MVC: It couldn't be simpler, right?

parallaxing 404 at github

Cool looking 404 pages are the new hotness. Github has an amazing parallaxing 404 page that allegedly cost more than any other feature on their site.

For a lot of sites, the 404 page is the most visited page, so it's worth getting it right.

The website for my new product, NimbleText, uses asp.net mvc. A framework I really enjoy. The gu wrote it on a plane. Before takeoff.

One of the more voodoo aspects of getting NimbleText.com into production was setting up a succesful custom 404 page. Here's what I came up with: check it out.

Some of the articles out there that cover custom errors in asp.net MVC seemed to be a little bit confused about exactly what is going on, many are out of date or incomplete and some are downright misleading.

So once and for all I want to give a definitive guide to error handling in asp.net MVC.

Here we are. Just eleven simple steps to follow for amazing results.

First, map a catch-all route in global.asax, at the end of your other routes. E.g.

routes.MapRoute(
   "404-PageNotFound",
   "{*url}",
   new { controller = "StaticContent", action = "PageNotFound" }
);

Second, create an Error Controller, like this:

public class ErrorController : Controller
{
   [AcceptVerbs(HttpVerbs.Get)]
   public ViewResult Unknown()
   {
     Response.StatusCode = (int)HttpStatusCode.InternalServerError;
     return View("Unknown");
   }

   [AcceptVerbs(HttpVerbs.Get)]
   public ViewResult NotFound(string path)
   {
     Response.StatusCode = (int)HttpStatusCode.NotFound;
     return View("NotFound", path);
   }
}

Third and fourth -- create custom views to handle the Unknown and NotFound actions above.

Fifth, create a page called Custom404.htm and add it to the root of your application. Use it to display a helpful, edgy and hopefully cool message. But don't be too edgy.

Sixth, add this to web.config, inside the system.web node:

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
   <error statusCode="404" redirect="/Custom404.htm" />
</customErrors>

Seventh, add a httpErrors element inside the system.webServer node:

<httpErrors>
   <error statusCode="404" subStatusCode="-1" path="/custom404.htm" responseMode="Redirect" />
</httpErrors>

Eighth, inside your existing controllers, if there is no data to serve (e.g. if someone asks for a UserId that doesn't exist) then use this snippet of code:

throw new HttpException(404);

Ninth, inside Global.asax, look for the RegisterGlobalFilters method (it will be called during Application_Start), and add another global filter, to handle any specific exceptions in your code, like this:

filters.Add(new HandleErrorAttribute
    {
        ExceptionType = typeof(FileNotFoundException),
        View = "Custom404", // Custom404.cshtml is a view in the Shared folder.
        Order = 2
    });

Tenth, add a view called Custom404.cshtml under views/shared.

And, eleventh, take care to handle the global application error event, capturing and logging any errors, before redirecting to the views you're after:

protected void Application_Error(object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Response.Clear();
    HttpException httpException = exception as HttpException;
    if (httpException != null)
    {
        string action;
        switch (httpException.GetHttpCode())
        {
            case 404:
                // page not found
                action = "HttpError404";
                break;
            case 500:
                // server error
                action = "Internal500";
                break;
        default:
            action = "General";
            break;
        }
        // clear error on server
        Server.ClearError();
        Response.Redirect(String.Format("~/Error/{0}/?message={1}", action, exception.Message));
    }
}
unexpected error

Good.

Now your website is well and truly borked.

Every request will bounce around your application like a demented pinball tripping on acid.

When an error happens, a bunch of different code modules will go to war.

The victorious code module will tear out the entrails of all those who oppose it, and throw them in the visitor's face.

You'll get a different error handler depending on what version of IIS you have, what version of MVC you're using, whether you've deployed in debug or release, whether you're visiting locally or remotely, whether it's sunny or raining.

Your server will be reduced to a pile of smouldering rubble from which reboot is impossible.

But if you want to get truly weird, try setting up a custom 403 page. That's about three times as odd.

Or, switch to Dos on Dope*. Life will be simple again.

Sorry I didn't really have time to write a definitive guide to this stuff. Error handling in MVC is crazy man, I'm busy fighting a clandestine war against hackers and crackers and bots and beuracrats: I can't be documenting that kind of mystery wrapped in an enigma.

If someone does write a complete guide to error handling in MVC, that includes the meaning and interaction behind each of these snippets, plus how the interplay between IIS, asp.net and MVC truly works, then I will happily update this article to include a link to it, right up top.


* Don't switch to Dos On Dope.





'troy' on Wed, 15 Jun 2011 08:53:49 GMT, sez:

This really is too hard.



'lb' on Mon, 25 Jul 2011 04:02:44 GMT, sez:

The other thing to do, in your errorcontroller is to add this:

Response.TrySkipIisCustomErrors = true;

That way asp.net will handle the error rather than iis taking over.



'Alan Stevens' on Sun, 25 Sep 2011 23:47:02 GMT, sez:

Leon, have you seen this?

http://nuget.org/List/Packages/MagicalUnicornMvcErrorToolkit

Are you to blame?

++Alan



'Bilal' on Thu, 17 Nov 2011 18:22:14 GMT, sez:

Complete worthless!

I tried to implement all of above and got compile error, i corrected them and then tried to access non existing pages or product id's and got the usual yellow asp.net error page, that is none of the custom error pages where shown!!!

Please before putting up and article like this. Try to implement it and see whether it is working. Otherwise you are just wasting our time.





name


website (optional)


enter the word:
 

comment (HTML not allowed)


All viewpoints welcome. But the right to delete any post for any reason is reserved. Don't make me do it. Aim for constructiveness. Comments may be republished, emailed to your loved ones or printed and used as toilet paper. Also, I get particularly nasty on comment spam. It's not worth even trying to post comment spam here -- your html is escaped, and your links are given a rel='nofollow'. By attempting to post a comment, you understand that if the comment is considered spam, at my absolute discretion, your IP address may be used as the target of a prolonged distributed denial of service attack. Your electricity might suddenly stop working. Your car tyres will go mysteriously flat. You will suffer permanent hairloss. Your dreams will be filled with terrifying monsters. And in any case I reserve the right to record and publish your IP address.

 

TimeSnapper is a life analysis system that stores and plays-back your computer use. It makes timesheet recording a breeze, helps you recover lost work and shows you how to sharpen your act.

 

NimbleText - FREE text manipulation and data extraction

NimbleText is a Powerful FREE Tool

Use it for:

  • extracting data from text
  • manipulating text
  • generating code

It makes you look awesome. Use it right now! Go on! Hurry! Don't walk, run!

 

Articles

Mind-boggling Demo of New Gaming Genre, aka Folder-Based Hangman, aka Fun with Recursion Mind-boggling Demo of New Gaming Genre, aka Folder-Based Hangman, aka Fun with Recursion
Got CSV in your javascript? Use agnes. Got CSV in your javascript? Use agnes.
I went to write down a book name and founded an internet empire instead. I went to write down a book name and founded an internet empire instead.
NimbleText: Origins NimbleText: Origins
The Windows 8 Mullet The Windows 8 Mullet
Cosby: spontaneous striped background generator Cosby: spontaneous striped background generator
Slides from WDCNZ: Live Coding Asp.net MVC3 Slides from WDCNZ: Live Coding Asp.net MVC3
MVC 3, MVC 3, "Third Times a Charm" references
Custom Errors in ASP.Net MVC: It couldn't be simpler, right? Custom Errors in ASP.Net MVC: It couldn't be simpler, right?
Anatomy of a Domain Hijacking, part 2: The Website Who Came In From The Cold Anatomy of a Domain Hijacking, part 2: The Website Who Came In From The Cold
Anatomy of a Domain Hijacking, part 1 Anatomy of a Domain Hijacking, part 1
secretGeek.net domain has been stolen. The site may go down. secretGeek.net domain has been stolen. The site may go down.
Boring article: 'untrusted domain' issue with SQL Server. Boring article: 'untrusted domain' issue with SQL Server.
Coding While You Commute Coding While You Commute
Test Driven Dentistry Is A Good Thing Test Driven Dentistry Is A Good Thing
The 'less crashy' release of NimbleText The 'less crashy' release of NimbleText
Rethinking Toolbars in Visual Studio (or any IDE) Rethinking Toolbars in Visual Studio (or any IDE)
Where shall we have lunch? Where shall we have lunch?
Setting up email for your microIsv Setting up email for your microIsv
The NO Visual Studio movement: Compiling .net projects in Notepad++ The NO Visual Studio movement: Compiling .net projects in Notepad++
ZeroOne: the editor for programmers who think in binary ZeroOne: the editor for programmers who think in binary
Mercurial workflow for personal projects (with a .net bias) Mercurial workflow for personal projects (with a .net bias)
I see you're using vim. Let me fix that for you. I see you're using vim. Let me fix that for you.
The worst recruitment spam I've ever read The worst recruitment spam I've ever read
A thank you I forgot to say A thank you I forgot to say
My new product, NimbleText, is live My new product, NimbleText, is live
Grabbing the free songs of Jonathan Coulton (with Powershell) Grabbing the free songs of Jonathan Coulton (with Powershell)
Using NimbleSet to compare lists Using NimbleSet to compare lists
Wanted: Wiki Lists (dot org) Wanted: Wiki Lists (dot org)
DOS on Dope: The last MVC web framework you'll ever need DOS on Dope: The last MVC web framework you'll ever need
JSON Query Languages: 5 special purpose editors JSON Query Languages: 5 special purpose editors
What then, is b? What then, is b?
SQLike: A simple editor SQLike: A simple editor
Yet Another BizPlan Generator. Yet Another BizPlan Generator.
HOT GUIDS: A hot or not site for guids HOT GUIDS: A hot or not site for guids
How does life get better? One tiny hack at a time. How does life get better? One tiny hack at a time.
24 things to do, and 100 things *not* to do (yet) for building a MicroISV 24 things to do, and 100 things *not* to do (yet) for building a MicroISV
Venture capital won't kill Jeff Atwood, it will only make him Jeffer. Venture capital won't kill Jeff Atwood, it will only make him Jeffer.
A handy workflow image for newbie mercurial users A handy workflow image for newbie mercurial users
Fractal Feedback, a diversion into recreational programming Fractal Feedback, a diversion into recreational programming
Hump-Jumping: How the Education of Computer Science can be Saved, err, maybe. Hump-Jumping: How the Education of Computer Science can be Saved, err, maybe.
Suggested User Experience Improvements for DiffMerge Suggested User Experience Improvements for DiffMerge
SQL Style Extensions for C# SQL Style Extensions for C#
The Movie Hollywood (And My Wife) Doesn't Want You To See: Weekend at Jacko's The Movie Hollywood (And My Wife) Doesn't Want You To See: Weekend at Jacko's
Sysi: the ultimate administrators toolkit Sysi: the ultimate administrators toolkit

Archives .: secretGeek :: Complete Archives
TimeSnapper -- Automated Screenshot Journal TimeSnapper.com    
Version 3.3: true productivity boost

Next Action NextAction
Managing the top of your mind

NimbleText -- World's Simplest Code GeneratorNimbleText -- World's Simplest Code Generator, Text Manipulator, Data Extractor

25 steps for building a Micro-ISV 25 steps for building a Micro-ISV
3 minute guides -- babysteps in new technologies: powershell, JSON, watir, F# 3 Minute Guide Series
Universal Troubleshooting checklist Universal Troubleshooting Checklist
Top 10 SecretGeek articles Top 10 SecretGeek articles
ShinyPower (help with Powershell) ShinyPower
Now at CodePlex

Realtime CSS Editor, in a browser RealTime Online CSS Editor
Gradient Maker -- a tool for making background images that blend from one colour to another. Forget photoshop, this is the bomb. Gradient Maker


[powered by Google] 


How to be depressed How to be depressed
You are not inadequate.



Recommended Reading


the little schemer


The Best Software Writing I
The Business Of Software (Eric Sink)

Recommended blogs

Jeff Atwood
Joseph Cooney
Phil Haack
Scott Hanselman
Julia Lerman
Rhys Parry
Joel Pobar
Thomas White
OJ Reeves
Eric Sink

Aggregated Links

proggit
dzone
hacker news
dot net kicks

Human Link Machines

interesting finds
a continuous learner's weblog
arjan's world
weekly link post

LinkedIn profile
LogEnvy - event logs made sexy
Computer, Unlocked. A rapid computer customization resource
PC Smart Buys - Computer Hardware in Australia
 
home .: about .: sign up .: sitemap .: secretGeek RSS .: © Leon Bambrick 2006 .: privacy

home .: about .: sign up .: sitemap .: RSS .: © Leon Bambrick 2006 .: privacy