How to Fix Server Error in Application in ASP.NET

There are other error that sometimes you can find when deploying your Asp.net application and some of our users also experiece this issue.

The CustomErrors element inside an ASP.NET/MVC/Web API Web.config file, is something almost everyone uses somehow, however, many people’s experiences don’t work like they expect. This post is an attempt to put down all of the things I have learned on “paper,” so you can avoid having to go through the same pain I did.

Let’s start by discussing what we can do with the customErrors element. When errors happen on your ASP.NET application, you want to tell the user that an error happened. Out of the box, ASP.NET provides an error page often referred to as the “Yellow Screen of Death” (YSoD):

The YSoD is the default fallback when no custom error page has been configured. YSoD works after deploying it to another server, but it looks different:

It’s the same page, but one is accessed through localhost and the other through a remote name. ASP.NET hides an application’s specific details like the stack trace, file locations, .NET version, etc., as a security feature. While the first example is quite fine when running locally and where you want to track down errors, the second is not very user friendly.

Before we start digging down into custom error pages, let me put a few words in on the possibilities listed in the screenshot above. As mentioned, you can add the following to the system.web element:

<configuration>
  <system.web>
    <customErrors mode="Off"/>
    ...
  </system.web>
  ...
</configuration>

Doing so will give you the detailed error message from the first screenshot, even when running in production. This approach is used by some developers while setting up the production environment or if everything fails.

Finally, let’s talk about some custom errors. So what exactly is a custom error? Actually, it’s just an HTML (typically) document like everything else. The page should explain to the user that something went wrong and it’s preferable to help the user move on by either proposing alternatives or giving them a way to contact support.

Different versions of ASP.NET come with different features. I’ll explain how MVC defines error pages later in this post, and why I’ll focus on ASP.NET WebForms first. We have already seen a possible value of the mode attribute (mode="Off"). To enable an error page, set the value to On and specify an error page in the defaultRedirect attribute:

<configuration>
  <system.web>
    <customErrors mode="On" defaultRedirect="~/Error.aspx"/>
    ...
  </system.web>
  ...
</configuration>

When an exception occurs, ASP.NET will automatically redirect the user to /Error?aspxerrorpath=/default.aspx.  The aspxerrorpath parameter is appended to the URL specified in defaultRedirect to help identify the page that caused the error. If you want ASP.NET to keep the user on the failing URL, but still show the error page, you can use the redirectMode attribute:

<configuration>
  <system.web>
    <customErrors mode="On" defaultRedirect="~/Error.aspx" redirectMode="ResponseRewrite"/>
    ...
  </system.web>
  ...
</configuration>

When setting redirectMode to ResponseRewrite the error page is shown, but the URL stays on /Default.aspx (which is the page where I’m throwing an exception). If you want to go back to the old behavior, either remove the redirectMode attribute or set it to ResponseRedirect.

If you are coding along you may have noticed that ASP.NET now shows the custom error page when running localhost. If you are using elmah.io or something similar to inspect your errors, this may not be a problem. But in most cases, having the YSoD when running locally is a huge advantage. To get this behavior, set mode to RemoteOnly:

<configuration>
  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/Error.aspx"/>
    ...
  </system.web>
  ...
</configuration>

As expected, ASP.NET now only redirects the user to the error page if the web application is accessed on a remote name other than localhost.

Another feature worth mentioning is the option of having multiple error pages. You may have a “funny” 404 page and another page reassuring users who experience a 500 that you are indeed looking at the error. To do just this, use error child elements:

<configuration>
  <system.web>
    <customErrors mode="RemoteOnly" defaultRedirect="~/Error.aspx">
      <error statusCode="404" redirect="~/Notfound.aspx" />
    </customErrors>
    ...
  </system.web>
  ...
</configuration>

The added error element tells ASP.NET to redirect the user to /Notfound.aspx if an exception is thrown and the status code is 404. You can define multiple error elements with each “listening” for an individual status code. If the returned status code doesn’t match one already specified in an error element, ASP.NET uses the value in defaultRedirect as a fallback.

ASP.NET MVC

ASP.NET MVC introduces new features for custom error pages, but everything is still built on top of the ASP.NET pipeline. When creating a new project using the template available in Visual Studio, you get an error page generated (Views/Shared/Error.cshtml) which you can style to meet your needs. The page is triggered using a combination of setting mode to On or RemoteOnly in web.config (as shown multiple times already) and by adding the MVC filter HandleErrorAttribute either on individual controllers and/or actions or simply as a global filter in FilterConfig.cs:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

This kind of custom error page can be fine for simple projects. However, in real life you want to look into something more elaborate since the HandleErrorAttribute only handles errors that happen within the context of MVC (500s basically).

 

 

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *