Is it possible to handle 404 errors only in ASP.Net? - c#

What web.config settings should I enter so that I can handle 404 errors but not other errors. The reason I want to handle 404 errors is that sometimes I purposely enter urls for inexisting pages but which I can handle and internally redirect to the real pages. That works fine, however, I do not want to handle other pages. On the contrary, I want to load the standard "non-custom" errors so that I can identify what is wrong with the page and see the line number causing the error. But when I enable custom errors for 404, I start getting redirected to the default error page (for 500 errors) and not have a clue of what caused the error.
Alternately I would consider having a custom error page that properly displays which page and which line is causing the error. I could do that for classic ASP but I could not find how to do that for ASP.Net.
Any help or pointers would be greatly appreciated.
Thanks!
P.S. not sure if it makes a difference, but my test server is IIS7.5 while the one for the live website is IIS6.

Try this:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/Errors/404.aspx" responseMode="ExecuteURL"/>
</httpErrors>
Please refer to the following post:
http://tedgustaf.com/en/blog/2011/5/custom-404-and-error-pages-for-asp-net-and-static-files/

Related

How can I elegantly handle server error where the database is unavailable in an ASP.NET application?

I have an ASP.NET web application. I've set up IIS 8.5 to handle various HTTP error responses using static HTML error page e.g.
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="500" subStatusCode="-1" />
...
<error statusCode="500" prefixLanguageFilePath="httpErrors\custom" path="500.htm" responseMode="File" />
...
</httpErrors>
</system.webServer>
I've also set my application to delegate exception handling to IIS because I want to be sure any exceptions which cause the application to fail are still handled elegantly. Therefore I've set my web.config as:
<system.web>
...
<customErrors defaultRedirect="~/CustomError.aspx" mode="On" />
...
</system.web>
CustomError.aspx just looks like this:
<%# Page Language="C#" %>
<script runat="server">
protected void Page_Init(object sender, EventArgs e)
{
Response.TrySkipIisCustomErrors = false;
Response.StatusCode = 500;
}
</script>
I'm trying to tell my application to defer to IIS for error handling.
If I now simulate a server error by throwing an exception I see my request is redirected to /CustomError.aspx?aspxerrorpath=/path/to/fracture.aspx. In this case the application's customErrors setting has kicked in presumably because the exception has been thrown in ASP.NET. However, what I see is my 500.htm page configured in httpErrors (see above).
If I simulate a server error a different way by simply setting Response.StatusCode = 500; then this time I am not redirected but I still see the contents of my 500.htm error page. Presumably this time IIS is handling the server error without the application's involvement.
Both these things are good :)
However, now I want to see what happens if my database goes down. To simulate this I change my connection string to point to a database which doesn't exist. Which of the above scenarios do you think I observe? Neither! What I actually see is a very ugly:
Server Error in '/template' Application.
Runtime Error
Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
I can see in the browser address bar that I've been redirected to CustomError.aspx so the application has handled the error as expected. You can see from the code of CustomError.aspx above that it makes no database calls. In fact it barely does anything. So why am I not seeing my nice friendly error page? I can even see from monitoring the request that it's still a 500 status code.
A lot of detail I know, but I'm really keen to find a standard and reliable approach to error handling that never exposes any ugly ASP.NET messages.

Umbraco 7 403 pages for multi-language pages

With multi-language sites in umbraco, 404 pages can be set in umbracoSettings.config so that the content can be translated.
<errors>
<error404>
<errorPage culture="default">//yourDocumentType[#nodeName='404']</errorPage>
</error404>
Normally setting other error codes would be set in the Web.config that would redirect to a static .net page.
<customErrors mode=“On“ defaultRedirect=“Error.aspx“>
<error statusCode=“403“ redirect=“Error.aspx“ />
<error statusCode=“404“ redirect=“Error.aspx“ />
</customErrors>
Is there a way of being able to set HTTP status codes for other languages like you can with 404 error codes in umbracoSettings.config
Sadly, as far as I know, this only works for 404 pages, I don't think you can use it to translate error pages for other status codes, sorry!

ASP.NET MVC customError page doesn't get displayed for some of the 400 errors

I'm having quite an interesting issue with the custom error pages management for a new ASP.NET MVC application.
This issue is like this:
- if I'm calling an URL (doesn't matter which) with a "bad" argument at the end of URL, like ..../c<, the application is displaying the correct server error page as instructed in the web.config;
- if I'm changing the URL to a more nasty one, like .../<c (to look more like an HTML tag, there is no more server error page displayed in the browser and instead of that, I'm getting a plain YSOD with a message like An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
According to ELMAH, both requests ended with a 400 status code and the message being:
- for the first one: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
- for the second one: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (<).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
So, both errors are the same, the status code is the same, but for one of the errors, the custom error page is not getting displayed. I've also went to global.asax in debug mode and checked the Server.GetLastError() in protected void Application_Error(object sender, EventArgs e) and again, both errors were the same, nothing is different.
In web.config, this is how my <customErrors> tag looks like:
<customErrors mode="On" defaultRedirect="/ServerError.aspx" redirectMode="ResponseRewrite">
<error statusCode="500" redirect="/ServerError.aspx" />
<error statusCode="404" redirect="/PageNotFound.aspx" />
</customErrors>
Can please someone tell me why the behavior is different in these two cases?
Thank you very much for your time.
There's a lot of misinformation and/or out-of-date solutions regarding error handling in IIS 7+. The main things to understand are:-
.NET 4.0 made breaking changes to ASP.NET's request validation.
IIS 7+ introduced a new way of handling custom error pages.
Most people are using hodge-podge solutions involving all of customErrors, httpErrors the Application_Error handler, and often setting requestValidationMode="2.0" on the httpRuntime property and/or disabling request validation entirely! This makes it really difficult to use other people's solutions because any and all of these can affect the behaviour. I had a quick search around and I found several semi-duplicates without accepted answers, probably for this reason.
The reason that these two errors give you different behaviour is that they occur at different stages in the request pipeline. The customErrors node in your web.config interacts with errors "inside" your application, while request validation takes place "outside" your application. IIS rejects the dangerous request before it gets to your application code, and so your customErrors replacement doesn't happen.
So how do we fix that?
Ideally you want a solution with as few moving parts as possible. IIS7 gives us a new way to specify error page replacement at the IIS level instead of at the application level - the httpErrors node. This lets us catch all our errors in one place:-
<configuration>
...
<system.webServer>
...
<httpErrors errorMode="Custom" existingResponse="Replace">
<clear />
<error statusCode="400" responseMode="ExecuteURL" path="/ServerError.aspx"/>
<error statusCode="403" responseMode="ExecuteURL" path="/ServerError.aspx" />
<error statusCode="404" responseMode="ExecuteURL" path="/PageNotFound.aspx" />
<error statusCode="500" responseMode="ExecuteURL" path="/ServerError.aspx" />
</httpErrors>
...
</system.webServer>
...
</configuration>
If you care about SEO (and you should!), you still have to make sure that your controller/page sets an appropriate status code:-
this.Response.StatusCode = 500; // etc.
You should remove your customErrors node entirely. It is normally used for backwards-compatibility. You should also ensure that requestValidationMode is not set on the httpRuntime node.
This should catch most errors (excluding, obviously, errors in parsing your web.config!)
Related:- ASP.NET MVC Custom Errors
MSDN Documentation:- http://www.iis.net/configreference/system.webserver/httperrors
Note: in your case, if you want to set defaultPath on the httpErrors node, you'll get a lock violation because of ApplicationHost.config settings. You can either do as I did and just set path individually for the error codes you care about, or you can have a look at unlocking the node:-
http://www.iis.net/learn/get-started/planning-your-iis-architecture/introduction-to-applicationhostconfig
http://forums.iis.net/t/1159721.aspx
My intuition is that it's more trouble than it's worth in low-control environments like Azure App Service / Azure Web Sites. You might as well set the paths for individual status codes.
I've put a full working example of using httpErrors for custom error pages up on github. You can also see it live on azure web sites.

I need to redirect the user to this one page in case of ANY kind of error

I added this in my webconfig file but its not redirecting. It shows the aspx error as it is with the Stack Trace and all:-
<customErrors mode="RemoteOnly" defaultRedirect="myhomepage.aspx"/>
What could be wrong? Please help me out.
I think you need the values as mode="On" so that it shows up the custom errors. This will allow custom errors for remote clients as well as localhost (while you debug) and it is not the case for RemoteOnly which ignores the localhost.
More details refer here
The way you've got it set up at the moment is that it will show that page for any users that are not on the same computer that IIS is running on. If you're testing it from localhost then it won't work (unless as V4Vendetta suggested you set the Mode to On).
RemoteOnly means.. Remote Only. In other words, you see the YSOD (Yellow Screen Of Death) when you view the page with the error if you are browsing from the same computer as the program is executing on.
If you view it from a different computer, then you will see your custom error page.
If you want to see the custom error even when browsing locally, then use mode="On".
If you are still not seeing the custom error message, even if browsing remotely, it probably means you did not add it to the correct section of the web.config. It should be in
<configuration>
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="myhomepage.aspx"/>
</system.web>
</configuration>

Display custom error page when file upload exceeds allowed size in ASP.NET MVC

My main issue is that I want to display an custom error page when an uploaded file exceeds allowed size (maxRequestLength in web.config).
When the big file is uploaded an HttpException is thrown before my upload action method in the controller is invoked. This is expected.
I have tried to catch the exception in a custom attribute and also to override OnException in the controller. Why isnt it possible to catch the exception in either the attribute or the OnException method?
Its possible though to catch the exception in Application_Error in global.asax but neither Response.Redirect nor Server.Transfer works for redirecting to the custom error page.
Server.Transfer gives the "failed to process child request" error and response.redirect gives the "Http headers already sent" error.
Any ideas?
Thanks in advance!
Marcus
When running under IIS7 and upwards there is another parameter:
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="10485760" />
</requestFiltering>
</security>
</system.webServer>
The default setting is slightly less than 30 MB.
For uploaded files with size between maxRequestLength and maxAllowedContentLength IIS7 will throw an HttpException with HTTP code 500 and message text Maximum request length exceeded. When this exception is thrown, IIS7 kills the connection immediately. So an HttpModule that redirects on this error will only work if the HttpException is handled and cleared (using Server.ClearError()) in Application_Error() in global.asax.cs.
For uploaded files with size bigger than maxAllowedContentLength IIS7 will display a detailed error page with error code 404 and subStatusCode 13. The error page can be found in C:\inetpub\custerr\en-US\404-13.htm
For redirects on this error on IIS7 I recommend redirecting on httpErrors instead.
To redirect to a different action set a smaller value for maxAllowedContentLength than maxRequestLength in web.config and also add the following to web.config:
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="13" />
<error statusCode="404" subStatusCode="13" prefixLanguageFilePath=""
path="http://yoursite.com/Error/UploadTooLarge" responseMode="Redirect" />
</httpErrors>
</system.webServer>
When running on IIS6, I solved it with a HttpModule by handling the BeginRequest and check if httpApplication.Context.Request.Length is larger than maxRequestLength.
To be able to redirect the entire request has to be read before redirecting.
See code example at this link:
http://www.velocityreviews.com/forums/t97027-how-to-handle-maximum-request-length-exceeded-exception.html
The velocity eviews link was really helpful in solving the issue. As stated, the only drawback was the entire request (and file) needs to be read before the redirection can be done.
But it can be limited to run only when the page where the file upload control is present by being loaded like this
if (HttpContext.Current.Request.Url.ToString().Contains("UploadedPage.aspx")
{
//read and process page request
}
You need to make a custom HttpHandler that will do this for you. ASP.NET will automatically kill the connection if the upload size is too large (as you found out).

Categories