Custom 404 and error pages

Topics: Customizing Orchard, General
Jul 7, 2011 at 8:23 PM

Is there currently a way to enable custom 404 and error pages in Orchard?

Thanks.

Coordinator
Jul 7, 2011 at 10:13 PM

Sure, web.config has a section for that, like any ASP.NET app.

Aug 31, 2011 at 2:04 AM

Hi Bertrand,

Can you expand a little more on this? I'm getting lost in the maze of web.config. I'm trying to setup a simple redirect for 404's. I added this to the root web.config:

    <customErrors mode="On">
      <error redirect="404.html" statusCode="404"/>
    </customErrors>
But it doesn't work. In fact, IIS won't even serve the file if I just try to browse to /404.html. This happens even on a fresh Orchard 1.2 install, so it appears that the main web.config that's shipping won't allow any static files to be served from the web root. I could of course put it in a folder of a theme which has the web.config for serving static files. But I'm curious why I can't put it in the web root folder? And like I said, the maze of configuration in that main web.config has me going cross eyed at the moment.  :-)

Coordinator
Aug 31, 2011 at 8:04 PM

We locked down security in the default web.config to disallow static files from the root, yes. You can add them back by doing the same thing that the web.config file in any scripts or content or styles is doing:

  <system.webServer>
    <handlers accessPolicy="Script,Read">
      <!--
      iis7 - for any request to a file exists on disk, return it via native http module.
      accessPolicy 'Script' is to allow for a managed 404 page.
      -->
      <add name="StaticFile" path="404.html" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
    </handlers>
  </system.webServer>

Aug 31, 2011 at 8:26 PM

Ah, yes, that seems to make sense. Although I'm still confused by what's already in the root web.config:

<handlers accessPolicy="Script">
  <!-- clear all handlers, prevents executing code file extensions, prevents returning any file contents -->
  <clear />
  <!-- Return 404 for all requests via managed handler. The url routing handler will substitute the mvc request handler when routes match. -->
  <add name="NotFound" path="*" verb="*" type="System.Web.HttpNotFoundHandler" preCondition="integratedMode" requireAccess="Script" />
</handlers>
So it first clears any default handlers, then adds the HttpNotFoundHandler. What's that doing exactly? If I add "Read" to the accessPolicy and add the StaticFile handler as you've shown either before or after that NotFound one, the theme for the site no longer works (although it does serve my 404 page now).

Coordinator
Aug 31, 2011 at 8:29 PM

Adding the not found handler enables the requests to return a 404. If that wasn't here, you'd get an empty response instead.

Coordinator
Aug 31, 2011 at 8:31 PM

Maybe change that name, although I'm not sure it will make a difference.

Aug 31, 2011 at 8:54 PM

Very strange. I've done this on two different machines now ... adding the StaticFile handler causes the theme to stop working - I just get back the raw html for the site. If I rename both StaticFile and NotFound, it still doesn't work. But if I rename them back to their original names, the theme starts working. Makes no sense to me.

However, on my second machine even after I did this, and added my customErrors node for the 404, it's not redirecting to the 404 page even when I give it a bogus url (like /foo). I can browse to the page after adding the handler, but it's not getting redirected there properly. I'll keep messing around with it tomorrow.

Sep 1, 2011 at 3:45 PM

Well, I'm completely stumped on this. I can get it to serve the 404.html file from the web root by adding the StaticFile handler (although that sometimes causes the theme to stop working until I rename it - I've observed this on multiple computers and Orchard installs. There doesn't seem to be any rhyme or reason to it though).

But I can't seem to ever get it to redirect to my custom error page no matter what I have in the <customErrors> section of <system.web> or the <httpErrors> in <system.webServer>. I always just get the default IIS 404 page. It seems that Orchard's MVC handler is always trying to handle the request, but the 404 that gets returned doesn't get redirected like I would expect. Below is the "detailed error information" section of the IIS 404 page. Has anybody gotten this to work successfully? It seems like a basic thing that I'm sure others have done, but for some reason it's just eluding me.

Detailed Error Information:

Module    ManagedPipelineHandler
Notification    ExecuteRequestHandler
Handler    Orchard.Mvc.Routes.ShellRoute+HttpAsyncHandler
Error Code    0x00000000
Requested URL    http://localhost:8528/foo
Physical Path    C:\Users\kkuebler\Documents\My Web Sites\JobsBlog\foo
Logon Method    Anonymous
Logon User    Anonymous
Request Tracing Directory    C:\Users\kkuebler\Documents\IISExpress\TraceLogFiles\JOBSBLOG
Sep 1, 2011 at 4:06 PM

Okay, just a few minutes after posting that I finally figured it out. The piece I was missing was adding errorMode="Cutom" to the <httpErrors> element. The <customErrors> node in <system.web> doesn't do anything in IIS 7.  :-)

So, my working configuration looks like this in <system.webServer>. Hopefully this helps keep anybody else from banging their head like I was doing. :-)

<system.webServer>
	<validation validateIntegratedModeConfiguration="false" />
	<modules runAllManagedModulesForAllRequests="true">
	  <remove name="WarmupHttpModule" />
	  <add name="WarmupHttpModule" type="Orchard.WarmupStarter.WarmupHttpModule, Orchard.WarmupStarter, Version=1.0.20, Culture=neutral" />
	</modules>
	<handlers accessPolicy="Script,Read">
	  <!-- clear all handlers, prevents executing code file extensions, prevents returning any file contents -->
	  <clear />
	  <!-- Return 404 for all requests via managed handler. The url routing handler will substitute the mvc request handler when routes match. -->
	  <add name="ErrorFiles" path="404.html" verb="*" modules="StaticFileModule" preCondition="integratedMode" resourceType="File" requireAccess="Read" />
	  <add name="NotFound" path="*" verb="*" type="System.Web.HttpNotFoundHandler" preCondition="integratedMode" requireAccess="Script" />
	</handlers>
	<directoryBrowse enabled="false" />
	<httpErrors errorMode="Custom">
		<clear />
		<error statusCode="404" subStatusCode="-1" path="/404.html" responseMode="Redirect" />
	</httpErrors>
</system.webServer>

Coordinator
Sep 1, 2011 at 6:08 PM

Ah, yes! Should have thought of that. I'm glad you could make it work, and sorry it took that much effort.

Nov 4, 2011 at 9:15 AM
Edited Nov 4, 2011 at 9:18 AM

thanks!