IIS custom 404 page - asp.net

As stated in the title i need to configure a custom web page for 404 error in my site (made with ASP.NET) and hosted on IIS.
To do so, i configure web.config as follow :
<httpErrors>
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/mycustompath/404.html" responseMode="ExecuteURL" />
</httpErrors>
Everything work just fine, if i type :
https://mydomain/path/page.aspx__somethingwrong__
i correctly go to my custom 404.html
Same happen if i put some random character instead of file
But if i mess up with the path, or type an unexisting .aspx file, then IIS redirect me to default 404 page. And is not clear to me why.
Example of url that does not work :
https://mydomain/invalid_path/page.aspx
https://mydomain/path/fictional_page.aspx

You can add errorMode="Custom" and existingResponse="Replace" in the web.config file to solve your problem.
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/MyErrorPages/404.html" responseMode="ExecuteURL" />
</httpErrors>
existingResponse specifies what happens to an existing response when the HTTP status code is an error, It also has 3 options:
auto(Default) : Leaves the response untouched only if the SetStatus
flag is set.
Replace : Replaces the existing response even if the SetStatus flag
is set. (means using custom page anyway)
Passthrough : Leaves the response untouched if an existing response
exists.

Related

ASP.NET MVC custom error pages stuck in a redirection loop

I'm trying to show custom error pages in my ASP.NET MVC app.
I understand that some errors are handles by ASP.NET and others by IIS.
The ASP.NET ones are handled and work fine
<customErrors mode="On" defaultRedirect="~/Error/Index"/>
When I request a URL that does not exist and references a static page like .html, I expect IIS to handle it.
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="http://localhost/MySite/404.html" responseMode="Redirect"/>
</httpErrors>
And that works. However I don't want to hard code http://localhost in there but make it a relative path.
So I tried
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="~/404.html" responseMode="Redirect"/>
</httpErrors>
However that keeps redirecting me (it appears) as the URL ends up being http://localhost/MySite/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/404.html
It also works if I do
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="404.html" responseMode="Redirect"/>
</httpErrors>
But of course only if the error is in http://localhost/MySite/doesnotexist.html root directory but not in any other like http://localhost/MySite/somedir/doesnotexist.html
If I change the responseMode to any of the other options it doesn't work at all, shows me the default IIS 404 page.
I'm deeply puzzled, what is causing the redirection loop?
I've been able to replicate the behaviour you are describing. Mine was fixed when I changed the responseMode to file. I.e. like this
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="404.html" responseMode="File" />
</httpErrors>
But maybe the problem is because you have put your 404.html in the mysite folder. Assuming it has to stay there I think it should work if you do this
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/mysite/404.html" responseMode="Redirect" />
</httpErrors>
The path attribute specifies the file path or URL that is served in response to the HTTP error specified by the statusCode and subStatusCode attributes. If you choose the File response mode, you specify the path of the custom error page. If you choose the ExecuteURL response mode, the path has to be a server relative URL (for example, /404.htm). If you choose the Redirect response mode, you have to enter an absolute URL (for example, www.contoso.com/404.htm).
The responseMode attribute specifies how custom error content is returned. The responseMode attribute can be one of the following possible values. Redirects client browsers to a the URL specified in the path attribute that contains the custom error file.
If responseMode is set to Redirect, the path value has to be an absolute URL.

How to send HTTP error code in Classic ASP with a HTTP subStatus?

In Classic ASP, I know that it's possible to return a HTTP Error Header by specifying the .Status property, like this :
Response.Status = "404 File Not Found"
But How can I return a more specific Error code with a substatus, for example 404.9 or 500.100 ?
I need to do that for testing purposes (as I know that the subStatus code is usually added by the server dynamically)
IIS will not log custom subcode in traffic logs.
Do not test for the subcode. Test for the statusText property returned by the custom error.
So : It seems that It is only possible to generate "three-digit" HTTP errors from Classic ASP code.
So the Only way to test if your custom webpages are working, is to call a "test.yyy" file located on the website.
As the file extension .yyy is not part of the IIS MimeMap, the static file handler will not serve it and then return a 404.3 error. This way, I can test my custom error pages.
This example comes from this Microsoft Article : https://www.iis.net/learn/troubleshoot/diagnosing-http-errors/how-to-use-http-detailed-errors-in-iis
So for everyone needing to set very detailed error messages including the HTTP subcodes under IIS 7 / 8, here is the "web.config" file contents for your website : (this file contains only a few entries, but you obviously can add entries for every HTTP code/subcode combination you want. Microsoft provides 56 error pages in C:\inetpub\custerr)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" subStatusCode="5" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-5.html" />
<error statusCode="404" subStatusCode="4" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-4.html" />
<error statusCode="404" subStatusCode="3" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-3.html" />
<error statusCode="404" subStatusCode="2" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-2.html" />
<error statusCode="404" subStatusCode="1" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-1.html" />
<error statusCode="404" subStatusCode="0" prefixLanguageFilePath="" path="E:\inetpub\vhosts\yourdomain.com\error_docs\404-0.html" />
</httpErrors>
</system.webServer>
</configuration>
I hope it will help ! :)

HttpError iis config throws exception when default path is added

I have this config which works and redirects the following errors correctly
<httpErrors errorMode="Custom"
existingResponse="Replace"
defaultResponseMode="ExecuteURL" >
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="403" responseMode="ExecuteURL" path="/Error/AccessDenied" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/PageNotFound" />
<error statusCode="500" responseMode="ExecuteURL" path="/Error/ApplicationError" />
</httpErrors>
But when I add the following default path to try to add a catch all
<httpErrors errorMode="Custom"
existingResponse="Replace"
defaultResponseMode="ExecuteURL"
defaultPath="/Error/ApplicationError">
The server throws a web.config error
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Module CustomErrorModule
Now this directly contradicts the documentation on msdn
Any help would be greatly appreciated!!
Using of defaultPath attribute prevents using of path attribute in your error nodes. So below configuration will work (but of course it will show the same error page for all HTTP errors defined here):
<httpErrors errorMode="Custom" existingResponse="Replace"
defaultResponseMode="ExecuteURL" defaultPath="/Error/ApplicationError">
<remove statusCode="403" />
<remove statusCode="404" />
<remove statusCode="500" />
<error statusCode="403" responseMode="ExecuteURL" />
<error statusCode="404" responseMode="ExecuteURL" />
<error statusCode="500" responseMode="ExecuteURL" />
</httpErrors>
Related doc: https://msdn.microsoft.com/en-us/library/ms690576(v=vs.90).aspx
You cannot override httpErrors "defaultPath" attribute in IISExpress because of applicationhost.config locked that attribute:
<httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
You can read more about it here: https://support.microsoft.com/en-us/kb/942055 This problem can occur:
when the specified portion of the IIS configuration file is locked at
a higher configuration level. To resolve this problem, unlock the
specified section, or do not use it at that level. For more
information on configuration locking, see How to Use Locking in IIS
7.0 Configuration.
This is becuase IIS by default (Ive just discovered this with IIS 10) at a server level locks defaultPath.
The error is saying some parent web.config attribute has been locked so you're not allowed to overwrite it.
The way to change this is to
Open IIS
Select the top level node in the tree (Your server/computer name most likely)
Click the 'Configuration Editor' icon in the last row.
Enter 'system.webServer/httpErrors' into the section dropdown at the top
Right click the defaultPath
Go to the 'defaultPath' attribute > sub menu
Click Unlock attribute
Click Apply Changes in the top right
I'd generally recommend against this though, as you'll have to do this on every server you deploy the site to.
(and I'm also not sure how something like Azure Web apps that dont give you this level of access handle it)
Try defaultPath="~/Error/ApplicationError" with ~.

I am using UrlRewritingNet.UrlRewrite dll, how to redirect to Error page when bad request get fired?

Currently I am using UrlRewritingNet.UrlRewrite dll for URL rewriting in Asp.Net #3.5.
Without using any special character it works fine ex. URL1.
But after giving special characters in URL it throws Bad Request error ex. URL2
URL1: http://www.example.com/search/0253
URL2: http://www.example.com/search/0253:0253
To handle this error, I want to redirect it to some other Error Page, How can I do this?
On IIS 7+ you can define error pages for all statuses, for 400 Bad Request :
<httpErrors>
<error statusCode="400" path="/bad-request.aspx" prefixLanguageFilePath="" responseMode="ExecuteURL"/>
</httpErrors>
or trough IIS console go to the error pages and add custom error page for status code 400 :
The best way is by using Web.config file like
<system.web>
<!-- other system.web stuff -->
<customErrors defaultRedirect="/Error404.aspx" mode="On" redirectMode="ResponseRewrite">
<error redirect="/Error404.aspx" statusCode="404" />
</customErrors>
</system.web>
<system.webServer>
<!-- other system.webServer stuff -->
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/Error404.aspx" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
For more details click here

HttpError will not show custom error pages

I've got this in the web.config:
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/Error/NotFound.aspx" responseMode="Redirect" />
<error statusCode="500" prefixLanguageFilePath="" path="/Error/ServerError.aspx" responseMode="Redirect" />
</httpErrors>
But IIS still shows the built in error page.
Any ideas?
You may also need to set the existingReponse attribute in the httpErrors element like this:
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear />
<error statusCode="404" prefixLanguageFilePath="" path="/ErrorHandler.aspx" responseMode="ExecuteURL" />
<error statusCode="500" prefixLanguageFilePath="" path="/ErrorHandler.aspx" responseMode="ExecuteURL" />
</httpErrors>
This is how I am using it and it works to me, it looks pretty similar except for the subStatusCode directives and the ExecuteURL.
<httpErrors>
<!--Remove inherited 500 error page setting -->
<remove statusCode='500' subStatusCode='-1'/>
<!--Override the inherited 500 error page setting with the 'My500.html' as its path-->
<error statusCode='500' subStatusCode='-1' prefixLanguageFilePath='' path='/My500.html' responseMode='ExecuteURL'/>
</httpErrors>
If you are using ExecuteURL, the custom error page path must be in the same application pool as the application itself.
For architectural reasons, IIS 7.0 can only execute the URL if it is located in the same Application Pool. Use the redirect feature to execute a Custom Error in a different Application Pool.
It seems as though you are using a server relative URL, try setting responseMode="ExecuteURL", from MSDN.
ExecuteURL
Serves dynamic content (for example,
an .asp file) specified in the path
attribute for the custom error. If
responseMode is set to ExecuteURL, the
path value has to be a server relative
URL. The numeric value is 1.
Redirect
Redirects client browsers to a the URL
specified in the path attribute that
contains the custom error file. If
responseMode is set to Redirect, the
path value has to be an absolute URL.
The numeric value is 2.
Ensure that you have the proper feature setting for the Error Page redirection in IIS. To check this, from the Error Pages page in IIS Manager, click Edit Feature Settings and make sure Custom error pages is checked if you are testing the redirects from the web server itself. If you are testing remotely, you can leave Detailed errors for local requests and custom error pages for remote requests is checked. This appears to be the default option in my test environment.

Resources