Cannot make custom error pages work in ASP.NET MVC application when running in application folder
<p>I have an ASP.NET MVC application, that is deployed in the Default web site in IIS and it runs inside an application folder, e.g. <code>http://localhost/appfolder</code>.</p>

<p>I have two error pages and I tried to set them using the <code>&lt;httpErrors&gt;</code> section in web.config. </p>

<pre><code>&lt;httpErrors errorMode="Custom" existingResponse="Replace"&gt;
    &lt;remove statusCode="401" /&gt;
    &lt;remove statusCode="500" /&gt;
    &lt;error statusCode="401" responseMode="ExecuteURL" path="/appfolder/Home/NoAccess" /&gt;
    &lt;error statusCode="500" responseMode="ExecuteURL" path="/appfolder/Home/Error" /&gt;
&lt;/httpErrors&gt;
</code></pre>

<p>The above setup works, but I could not make it work without using the folder name inside the paths. Based on the <a href="https://www.iis.net/configreference/system.webserver/httperrors/error" rel="nofollow">documentation</a> the <code>path</code> attribute is relative to the site root. </p>

<blockquote>
  <p>If you choose the ExecuteURL response mode, the path has to be a
  server relative URL (for example, /404.htm).</p>
</blockquote>

<p>So, with the above in mind, the following should work, but it doesn't.</p>

<pre><code>&lt;httpErrors errorMode="Custom" existingResponse="Replace"&gt;
    &lt;remove statusCode="401" /&gt;
    &lt;remove statusCode="500" /&gt;
    &lt;error statusCode="401" responseMode="ExecuteURL" path="/Home/NoAccess" /&gt;
    &lt;error statusCode="500" responseMode="ExecuteURL" path="/Home/Error" /&gt;
&lt;/httpErrors&gt;
</code></pre>

<p>Also, using <code>~/Home/NoAccess</code> does not work at all, it seems that IIS simply puts <code>~</code> in the URL. </p>

<p><strong>My question</strong>: Is it possible to have the above setup without having to use application folder name?</p>

<p><strong>Edit</strong>: See in this snippet how my application is authorizing each request.</p>

<pre><code>public class AppAutorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = false;
        // Business logic to decide if authorized
        return authorized;
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
}
</code></pre>

<p>And its use in a controller is:</p>

<pre><code>[HttpGet]
[AppAutorize]
public ActionResult Item(int id)
{
    Models.Home.Item model = new Models.Home.Item(id);

    return View("Item", model);
}
</code></pre>