Is it necessary to log http 404 exceptions - asp.net

I have below code in global application error event. If there is any invalid url, this event gets fired. Is it required to log http 404 errors.
void Application_Error(object sender, System.EventArgs e)
{
Exception lastException = HttpContext.Current.Server.GetLastError();
//log exception
}

The question is quite general, but logging 404 pages is quite good for several reasons.
By logging 404 pages you can find broken links on your web site and also to see how frequent it happens, that way you can create redirects if needed.
But it's your choice of course if you want to that or not.

Most servers are configured to write 404s along with all other requests and responses to its access log.

It's on your own if you want to log this error. Errors can also be handled automaticly using web.config inside system.web section, like this:
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
Basicly server will automaticly redirect to declared pages on specific error number.

The answer to your question is quite simply: "No, it's not required to log 404 errors."
It is best practice to have a process in place for handling 404 errors to maximize the search engine optimization of your site, though.

Related

ASP.NET redirect the page to a new URL

I have a site which has a start up page called Test.htm. The site is temporarily down and we want to display an error page when the site loads. I have a page called error.htm. How is this possible ??
Thanks in advance!
ASP.NET provides three main methods that allow you to trap and respond to errors when they occur: Page_Error, Application_Error, and the application configuration file (Web.config).
1.The Page_Error event handler provides a way to trap errors that occur at the page level
2.You can use the Application_Error event handler to trap errors that occur in your application
3.If you do not call Server.ClearError or trap the error in the Page_Error or Application_Error event handler, the error is handled based on the settings in the section of the Web.config file.
In the section, you can specify a redirect page as a default error page (defaultRedirect) or specify to a particular page based on the HTTP error code that is raised.
e.g. You need to add following code in Global.asax page customErrors section to redirect the user to a custom page
<customErrors defaultRedirect="http://hostName/applicationName/errorStatus.htm" mode="On">
</customErrors>
Take it "offline"
See: IIS: Redirect ALL requests to one page?
Just a thought but have looked a response.redirect?
In ASP.NET MVC, how does response.redirect work?
You can hack your web.config to force your application into returning 404's when requested. Then override the 404 error page to be you "error" page.
<httpRuntime enable="false" />
<customErrors mode="On" defaultRedirect="~/errors/GeneralError.aspx">
<error statusCode="404" redirect="~/error.htm" />
</customErrors>
You can use the app_offline.htm page. If the asp.net find this page on root, then what ever you ask its show this page, and the site is down.
Second way, that is not bring the site down, on Application Begin Request, make the redirect to the page you like as:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
string cTheFile = HttpContext.Current.Request.Path;
// just double check in case that htm proceed from asp.net
if(!cTheFile.EndsWith("test.htm"))
{
System.Web.HttpContext.Current.Response.Redirect("test.htm", true);
return;
}
}

how to redirect 404 (bad urls) to the homepage

I am using asp.net and when I type a bad url manually(in the browser) it gives me:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
I want a bad url that doesn't exist to be re-directed to the home page.
How do I do this? I am using sitemap.
If you have no intentions of letting the users know, they are being redirected. Then, you could just turn custom errors on and do something like this:
<configuration>
<system.web>
<customErrors defaultRedirect="default.aspx" mode="On">
<error statusCode="404" redirect="default.aspx"/>
</customErrors>
</system.web>
</configuration>
As others have already answered, web.config is one way to go.
The other is to catch unhandled exceptions from within your application. This gives you more control of the redirect.
protected void Application_Error(object sender, EventArgs e)
{
HttpException httpException = Server.GetLastError() as HttpException;
if (httpException.GetHttpCode() == 404)
Response.Redirect("/MainPage.aspx");
}
Remember that if you create your own 404-page you must:
Add 404-code to the Response manually.
Keep the reply body above 512 bytes or the browser will show its default error message instead.
Add this section to your web.config:
<customErrors mode="On" defaultRedirect="{yourDefaultErrorPage}">
<error statusCode="404" redirect="{yourhomePage}"/>
</customErrors>
customErrors Element on MSDN.
If you can, try have your 404 pages permanent redirect to a similar URL.
So instead of 404 response, make a 301 response to a similar URL on your site. Best SEO wise

IIS7 page redirection with 403 error

First of all, I'm not so close and familiar with IIS7 and using it just for redirection to a weblogic application.
The backend weblogic application which I use has a login page as a starter page. When I call the page through IIS7, it redirects my requests to weblogic and I see login page. When I try to login with correct pass&user name pair everthing goes fine I can use the system without any problem. However when I try to login with wrong credentials, IIS shows me defaul 403 permission denied page instead of my weblogic applications login error page.
When I dig the problem a litte bit, I found out that weblogic replys my wrong login attempt with a 403 message which already includes weblogic applications login failed page and when IIS see 403 message, it discards the page in it and just sends me pure 403 response (I've deleted IIS's fancy 403 error message, as well)
Is there any way that iis7 to redirect all requests and responeses without processing it? Changing the reply message code of weblogic application is out of question, unfortunately.
We had an issue where IIS 7 was catching errors responses sent back by weblogic through the ISAPI filter. For example if you put the wrong log in credentials to the log in page. IIS was returning a custom 403 error page and not sending back our apps log in page in weblogic.
This is due to IIS 7 handling custom error codes and sending back its own error pages. See more info at http://www.iis.net/ConfigReference/system.webServer/httpErrors
In order to correct this behavior, we had to set the
existingResponse='PassThrough' in the httpErrors section of the web.config for the website.
I'm not sure because I do not use the IIS. It might be enough if you are modifying the paths in the web.config file as follows:
<httpErrors>
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/index.php" responseMode="ExecuteURL" />
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath="" path="/weblogic/login.php" responseMode="ExecuteURL" />
</httpErrors>

ASP.NET membership can I get a directory to return 403?

I have an existing app that I've been doing some authentication work on (fixing some long standing issues) and I'm happy enough with the login redirection under normal circumstances. For IIS7 I'm implementing an authorization HttpModule that I'm running on the whole IIS7 pipeline.
This works great but I'd like to get some subdirectories (actually virtual directories) of the main site to return 403 instead of a redirect. Is it possible to do this without implementing my own authentication module?
I've seen Sky Sanders work (code poet) but I'd like to avoid that if I can.
http://www.codeproject.com/Articles/39062/Salient-Web-Security-AccessControlModule.aspx
It feels like something clever with a <location=""> section should work but I can't figure out how to do that (or if it's even possible).
Try creating a separate web.config for the sub directories and denying access to them (sub directory) using the deny verb in the sub directory's web.config. Something like deny="?" (? is the verb that identifies authenticated users). If you want a 403 for everybody try * instead of ?. I think this should work.
Try this:
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm"/>
<error statusCode="404" redirect="FileNotFound.htm"/>
</customErrors>
(Source: MSDN)
If this doesn't cut it, also add this in your Global.asax:
void Application_EndRequest(object sender, EventArgs e)
{
// if login failed then display user friendly error page.
if (Response.StatusCode == 403)
{
Response.ClearContent();
Server.Transfer("~/Common/Errors/AccessDenied.html");
}
}
Hope this works.

IIS7 Overrides customErrors when setting Response.StatusCode?

Having a weird problem here. Everybody knows that if you use web.config's customErrors section to make a custom error page, that you should set your Response.StatusCode to whatever is appropriate. For example, if I make a custom 404 page and name it 404.aspx, I could put <% Response.StatusCode = 404 %> in the contents in order to make it have a true 404 status header.
Follow me so far? Good. Now try to do this on IIS7. I cannot get it to work, period. If Response.StatusCode is set in the custom error page, IIS7 seems to override the custom error page completely, and shows its own status page (if you have one configured.)
Has anyone else seen this behavior and also maybe know how to work around it? It was working under IIS6, so I don't know why things changed.
Note: This is not the same as the issue in ASP.NET Custom 404 Returning 200 OK Instead of 404 Not Found
Set existingResponse to PassThrough in system.webServer/httpErrors section:
<system.webServer>
<httpErrors existingResponse="PassThrough" />
</system.webServer>
Default value of existingResponse property is Auto:
Auto tells custom error module to do the right thing. Actual error text seen by clients will be affected depending on value of fTrySkipCustomErrors returned in IHttpResponse::GetStatus call. When fTrySkipCustomErrors is set to true, custom error module will let the response pass through but if it is set to false, custom errors module replaces text with its own text.
More information: What to expect from IIS7 custom error module
The easiest way to make the behavior consistent is to clear the error and use Response.TrySkipIisCustomErrors and set it to true. This will override the IIS global error page handling from within your page or the global error handler in Application_Error.
Server.ClearError();
Response.TrySkipIisCustomErrors = true;
Typically you should do this in your Application_Error handler that handles all errors that your application error handlers are not catching.
More detailed info can be found in this blog post:
http://www.west-wind.com/weblog/posts/745738.aspx
Solved: It turns out that "Detailed Errors" needs to be on in order for IIS7 to "passthrough" any error page you might have. See http://forums.iis.net/t/1146653.aspx
I'm not sure if this is similar in nature or not, but I solved an issue that sounds similar on the surface and here's how I handled it.
First of all, the default value for existingResponse (Auto) was the correct answer in my case, since I have a custom 404, 400 and 500 (I could create others, but these three will suffice for what I'm doing). Here are the relevant sections that helped me.
From web.config:
<customErrors mode="Off" />
And
<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
<clear />
<error statusCode="404" path="/errors/404.aspx" responseMode="ExecuteURL" />
<error statusCode="500" path="/errors/500.aspx" responseMode="ExecuteURL" />
<error statusCode="400" path="/errors/400.aspx" responseMode="ExecuteURL" />
</httpErrors>
From there, I added this into Application_Error on global.asax:
Response.TrySkipIisCustomErrors = True
On each of my custom error pages I had to include the correct response status code. In my case, I'm using a custom 404 to send users to different sections of my site, so I don't want a 404 status code returned unless it actually is a dead page.
Anyway, that's how I did it. Hope that helps someone.
This issue has been a major headache. None of the suggestions previously mentioned alone solved it for me, so I'm including my solution. For the record, our environment/platform uses:
.NET Framework 4
MVC 3
IIS8 (workstation) and IIS7 (web server)
Specifically, I was trying to get an HTTP 404 response that would redirect the user to our custom 404 page (via the Web.config settings).
First, my code had to throw an HttpException. Returning a NotFoundResult from the controller did not achieve the results I was after.
throw new HttpException(404, "There is no class with that subject");
Then I had to configure both the customErrors and httpError nodes in the Web.config.
<customErrors mode="On" defaultRedirect="/classes/Error.aspx">
<error statusCode="404" redirect="/classes/404.html" />
</customErrors>
...
<httpErrors errorMode="Custom" existingResponse="Auto" defaultResponseMode="ExecuteURL">
<clear />
<error statusCode="404" path="/classes/404.aspx" responseMode="ExecuteURL" />
</httpErrors>
Note that I left the existingResponse as Auto, which is different than the solution #sefl provided.
The customErrors settings appeared to be necessary for handling my explicitly thrown HttpException, while the httpErrors node handled URLs that fell outside of the route patterns specified in Globals.asax.cs.
P.S. With these settings I did not need to set Response.TrySkipIisCustomErrors
TrySkipIisCustomErrors is only a part of a puzzle. If you use Custom Error Pages but you also want to deliver some RESTful content based on 4xx statuses then you have a problem. Setting web.config's httpErrors.existingResponse to "Auto" does not work, because .net seems to always deliver some page content to IIS, therefore using "Auto" causes all (or at least some) Custom Error Pages to be not used. Using "Replace" won't work too, because response will contain your http status code, but its content will be empty or filled with Custom Error Page. And the "PassThrough" in fact turns the CEP off, so it can't be used.
So if you want to bypass CEP for some cases (by bypassing I mean returning status 4xx with some content) you will need additional step: clean the error:
void Application_Error(object sender, EventArgs e)
{
var httpException = Context.Server.GetLastError() as HttpException;
var statusCode = httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError;
Context.Server.ClearError();
Context.Response.StatusCode = statusCode;
}
So if you want to use REST response (i.e. 400 - Bad Request) and send some content with it, you will just need to set TrySkipIisCustomErrors somewhere in action and set existingResponse to "Auto" in httpErrors section in web.config. Now:
when there's no error (action returns 4xx or 5xx) and some content is returned the CEP is not used and the content is passed to client;
when there's an error (an exception is thrown) the content returned by error handlers is removed, so the CEP is used.
If you want to return status with empty content from you action it will be treated as an empty response and CEP will be shown, so there's some room to improve this code.
By default IIS 7 uses detailed custom error messages so I would assume that Response.StatusCode will equal 404.XX rather than just 404.
You can configure IIS7 to use the simpler error message codes or modify your code handling the more detailed error messages that IIS7 offers.
More info available here:
http://blogs.iis.net/rakkimk/archive/2008/10/03/iis7-enabling-custom-error-pages.aspx
Further investigation revealed I had it the wrong way around - detailed messages aren't by default but perhaps they've been turned on, on your box if you're seeing the different error messages that you've mentioned.

Resources