10

I've been consolidating some of my web apps into one main ASP.NET MVC project; assigning some of them to separate Areas, so that they can be accessed via subdomains.

Using this (quite helpful) resource (https://dusted.codes/demystifying-aspnet-mvc-5-error-pages-and-error-logging), I've set up customErrors and httpErrors in the Web.config, so that custom error pages are displayed. Works well.

I'll use different layout/styling per Area/subdomain, so I'm wondering: How can I get an Area to display its own set of error pages?

With the current setup, all the subdomains will display the main set of custom errors that are added to the customErrors and httpErrors sections (403.html, 404.html, et cetera); but I'd prefer tailored error pages for some subdomains. (If one of the areas is exclusively handled by a separate domain altogether, for example, it won't be practical to serve the regular error pages.)

Update: Here is the scenario, with code, as requested. Thanks to Ben Foster, who offered good guidance here: http://benfoster.io/blog/aspnet-mvc-custom-error-pages2. I've put the code for customErrors, but not the corresponding httpErrors... left it out for brevity.

  <system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
      <error statusCode="404" redirect="~/404.aspx" />
      <error statusCode="500" redirect="~/500.aspx" />
    </customErrors>
  </system.web>

  <location path="MyArea1">
    <system.web>
      <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea1/500.aspx">
        <error statusCode="404" redirect="~/Areas/MyArea1/404.aspx" />
        <error statusCode="500" redirect="~/Areas/MyArea1/500.aspx" />
      </customErrors>
    </system.web>
  </location>

  <location path="MyArea2">
    <system.web>
      <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/Areas/MyArea2/500.aspx">
        <error statusCode="404" redirect="~/Areas/MyArea2/404.aspx" />
        <error statusCode="500" redirect="~/Areas/MyArea2/500.aspx" />
      </customErrors>
    </system.web>
  </location>

The above code works well:

  • If I navigate to "example.com/does/not/exist", I get the expected error page at ~/404.aspx.
  • If I navigate to "example.com/MyArea1/does/not/exist", I will get the custom error page at ~/Areas/MyArea1/404.aspx.

The challenge:

Now I'd like an Area (MyArea2) to be served by a totally separate domain (e.g. exampleOnMyOtherDomain.com), using HostDomainConstraint (as recommended by @TetsuyaYamamoto, in a comment below). A link that would have been accessible via "example.com/MyArea2/validlink" will now be accessed this way: "exampleOnMyOtherDomain.com/validlink".

Now, if I try "exampleOnMyOtherDomain.com/does/not/exist", I'll be served the top-level 404 (~/404.aspx). This is probably because "MyArea2" is not in the path anymore, so the location with the path "MyArea2" will not be picked up.

How can I get the Area (MyArea2) to serve its own error pages?

5
  • 1
    Probably location settings may help, see the reference: msdn.microsoft.com/en-us/library/ms178692.aspx. It can contains different content inside <system.web> element on each location, allowing customErrors and httpErrors to be set for different area by specifying area relative path. Commented Oct 13, 2016 at 5:07
  • Thanks @TetsuyaYamamoto; this was a pretty useful comment. I tried the location element, and when my Areas are a subpath of my main domain (e.g. example.com/MyArea), the location element works quite fine (path="MyArea")! But here's the problem: When my Area is served up by a separate domain altogether, I can't use the same strategy (e.g. myotherexample.net). Commented Oct 13, 2016 at 18:52
  • Thanks @TetsuyaYamamoto; edited the question. Commented Oct 14, 2016 at 18:42
  • After looking to your web.config area setting, I assume you can use Application_Error to handle errors from myotherexample.net to MyArea2 using Request.Url.Host. Additionally, you may set MapRoute to handle MyArea2 as part of redirect area path, followed by IIS URL rewriting module as there: iis.net/expand/URLRewrite. Commented Oct 14, 2016 at 23:42
  • I've added an answer @TetsuyaYamamoto; pleas share your thoughts on it. Commented Oct 18, 2016 at 14:21

1 Answer 1

6

Based on some research, and helpful pointers from @TetsuyaYamamoto, I've employed the strategy below.

I'm handling the "Application_Error" event in Global.asax, using the following code:

protected void Application_Error(object sender, EventArgs e)
{
    string hostName = Request.Headers["host"].Split(':')[0];
    if (hostName.Contains("exampleOnMyOtherDomain"))
    {
        Exception exception = Server.GetLastError();
        Response.Clear();
        HttpException httpException = exception as HttpException;
        Response.TrySkipIisCustomErrors = true;

        switch (httpException.GetHttpCode())
        {
            case 404:
                Response.StatusCode = 404;
                Server.Transfer("~/Errors/MyArea2_404.htm");
                break;
            case 500:
            default:
                Response.StatusCode = 500;
                Server.Transfer("~/Errors/MyArea2_500.htm");
                break;
        }
        Server.ClearError();
    }
}

Points to note:

  • hostName.Contains("exampleOnMyOtherDomain") should compare the Host name with the Area I'm interested in handling. I'll add else...if statements for other Areas;
  • Response.TrySkipIisCustomErrors = true should prevent IIS from attempting to handle the error;
  • Response.StatusCode sets the status code appropriately ('404', '500'...);
  • Server.Transfer() reads in a file that I'd like to display as the error page;
  • Server.ClearError() should signal that the error has already been handled.

I want customErrors/httpErrors to continue handling regular errors. When execution passes through the Application_Error block without being handled (i.e. Server.ClearError() isn't called), customErrors/httpErrors will handle the error.

It seems that this is a decent strategy for handling errors for Areas that are served by a different domain.

Sign up to request clarification or add additional context in comments.

3 Comments

IMHO this strategy was able to fulfill the separated domain handling for custom error pages, however you need to watch that TrySkipIisCustomErrors was properly working. If the redirection to area error page won't work, check that <httpErrors errorMode="Custom" existingResponse="PassThrough" /> is in place if IIS has been set to integrated mode, see this reference: msdn.microsoft.com/en-us/library/ms690576(v=vs.90).aspx.
Will do. Thanks @TetsuyaYamamoto, for all your help!
I have similar problem, I try to set different custom 404 pages for each areas? I have this in my web.config httpErrors <error statusCode="404" path="/Error/NotFound/" responseMode="ExecuteURL" /> This routes main 404 page, but I try to show different 404 page if route has an area myhost/area/notfound/route should show myhost/myArea/Error/NotFound. Should I ask a new question, if not how should I modify this solution?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.