Reputation: 8079
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. http://localhost/appfolder
.
I have two error pages and I tried to set them using the <httpErrors>
section in web.config.
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="401" />
<remove statusCode="500" />
<error statusCode="401" responseMode="ExecuteURL" path="/appfolder/Home/NoAccess" />
<error statusCode="500" responseMode="ExecuteURL" path="/appfolder/Home/Error" />
</httpErrors>
The above setup works, but I could not make it work without using the folder name inside the paths. Based on the documentation the path
attribute is relative to the site root.
If you choose the ExecuteURL response mode, the path has to be a server relative URL (for example, /404.htm).
So, with the above in mind, the following should work, but it doesn't.
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="401" />
<remove statusCode="500" />
<error statusCode="401" responseMode="ExecuteURL" path="/Home/NoAccess" />
<error statusCode="500" responseMode="ExecuteURL" path="/Home/Error" />
</httpErrors>
Also, using ~/Home/NoAccess
does not work at all, it seems that IIS simply puts ~
in the URL.
My question: Is it possible to have the above setup without having to use application folder name?
Edit: See in this snippet how my application is authorizing each request.
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);
}
}
And its use in a controller is:
[HttpGet]
[AppAutorize]
public ActionResult Item(int id)
{
Models.Home.Item model = new Models.Home.Item(id);
return View("Item", model);
}
Upvotes: 0
Views: 1328
Reputation: 513
Because your web application is hosted under another website the correct site relative path for the error pages would be the one you said works. I know this isn't what you was hoping to see but the best way of handling this is to replace that httpErrors
element in the Web.Release.config
file like the following:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document Transform">
<system.webServer>
<httpErrors xdt:Transform="Replace">
<remove statusCode="401" />
<remove statusCode="500" />
<error statusCode="401" responseMode="ExecuteURL" path="/appfolder/Home/NoAccess" />
<error statusCode="500" responseMode="ExecuteURL" path="/appfolder/Home/Error" />
</httpErrors>
</system.webServer>
</configuration>
And keep the standard Web.config
with the path excluding the appfolder path.
I tend to shy away from using the web config and instead set the HTTP errors to the following:
<httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" />
I then have a base controller which all my controllers inherit from with methods for each error code which I want a custom page for. So in your case:
public ViewResult NoAccess()
{
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
return View("NoAccess");
}
Then the usage in any of your controllers is very simple:
public ActionResult Test()
{
return NoAccess();
}
This will then render your custom view. This method of doing error pages depends on your use case but that's how I've managed to get custom error pages to work.
Upvotes: 1