Custom error pages based on path/URL in ASP.NET - c#

I have some pages in /panel/ directory and some in /website/ directory. I need two different 404 pages for these pages based on their path, because these directories have different master pages.
when I use customErrors in web.config file, it redirects all pages to one 404 page so it's useless for me.
How can I handle it? Can I handle it in global.asax or master pages or what?
Thanx in advance.

You can either create smaller web.config on those locations with the settings you want to override, or on the root web.config you specify the multiple customErrors settings inside location tags.
You don't need to change any code for this.

You want to handle errors in the Global.asax file:
void Application_Error(object sender, EventArgs e)
{ Exception exc = Server.GetLastError();
if (exc is HttpUnhandledException)
{ // Pass the error on to the error page.
Server.Transfer("ErrorPage.aspx?handler=Application_Error%20-%20Global.asax", true); } }
Check out this link for more info

Related

When I try to do routing I get a parse error in ASP.NET Web Forms

I published the web site and uploaded it to FTP (ASP.NET Web Forms C#).
I use routing in the project and this is my routing page's code (I only write 1):
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("HomePage", "HomePage", "~/Views/Default.aspx");
}
And my folders and pages are as follows:
The code of the Default.aspx page outside the Views folder:
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("/Views/");
}
When I try to enter mywebsite.com and enter the site, I get the following error:
But when I try to enter mywebsite.com/HomePage it works. I want to go to the main page when I write the site name directly. Where do I make mistakes?
I forgot to add: It's working on local btw. But doesn't work on FTP.
You have your routing configured incorrectly. The the home page URL is setup as HomePage instead of an empty string (/HomePage).
routes.MapPageRoute("HomePage", "HomePage", "~/Views/Default.aspx");
Change that to (/):
routes.MapPageRoute("HomePage", "", "~/Views/Default.aspx");
Also, delete your "Default.aspx page outside of Views folder". That is going to conflict with your routing and (even worse) it will cause an HTTP 302 redirect to your home page. An HTTP 302 redirect returned from the request tells the user's browser to make a second request to your server, which is bad for both performance and SEO reasons.
Given that your /HomePage URL is working correctly, the above changes should fix your problem.

Redirect Loop for Custom Errors Page

For error handling, I have added the following code to Web.config:
<system.web>
<customErrors mode="On" defaultRedirect="~/Error.cshtml?">
</customErrors>
<system.web>
And in Global.asax.cs:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Response.Redirect("/Error.cshtml?");
}
However, when the redirect to /Error.cshtml? occurs, there is an error 'This page has a redirect loop'
I've searched through other similar questions (such as How to solve Redirect Loop). However, I have no other routes calling Error.cshtml -- so does anyone have any idea what is causing this loop and how I can work around it?
EDIT: There are multiple errors occurring, and therefore the error page redirect is involved in a redirect loop. Does anyone know of a way to only call Response.Redirect("~/Error.cshtml") once?
EDIT2: If I change the redirect url to a random url outside of the project (such as https://www.facebook.com/), the customError redirect works properly. Still looking for a way to redirect to project page without infinitely looping through the error
Try adding:
Server.ClearError();
first to clear the existing error before redirecting.
Add redirectMode="ResponseRewrite" to customErrors section.

Server.Transfer causing Session exception

In my global I have the following code to handle when an error occurs
//[..] code goes here
Server.Transfer("~/Error.aspx?ErrorID=" + errorId);
It used to be a Response.Redirect which worked perfectly except that it changed the url (which is why I want to use Server.Transfer)
Unfortunately, now when it tries to load the Error page, it crashes on the Masterpage when it tries to refer to the Session
HttpException:
Session state can only be used when enableSessionState is set to true,
either in a configuration file or in the Page directive. Please also
make sure that System.Web.SessionStateModule or a custom session state
module is included in the \\
section in the application configuration.
I do have enableSessionState in both my config and my page.
I also found some links which suggest using Context.RewritePath - that just causes a blank page to load for me.
Using Response.Redirect works perfectly and as expected, so I assume Server.Transfer is the issue here. What is it?
EDIT Code:
protected void Application_Error(object sender, EventArgs e)
{
lock (_lockMe)
{
Exception ex = Server.GetLastError();
if (ex != null)
{
if (ex.InnerException != null)
ex = ex.InnerException;
ErrorLoggingManager.AddError(ex, new MembershipData(), ...); //etc
}
Server.ClearError();
//Some other database code for cleaning up some stuff when an error happens
}
try
{
if (Response != null)
{
//Get the last error logged
MyDataContext db = new MyDataContext();
int errorId = db.LoggedErrors.OrderByDescending(le => le.ErrorId).Select(le => le.ErrorId).FirstOrDefault();
Server.Transfer("~/Error.aspx?ErrorID=" + errorId);
}
}
catch (Exception)
{
}
}
As you have not posted much code. So without seeing the actual implementation you have done. I could suggest you below points.
Point 1. First of all, you need to check if SessionState is enabled for pages. You could set them globally in web.config file. Try the snippet given below in web.config
<configuration>
<system.web>
<pages enableSessionState="true" />
</system.web>
</configuration>
Point 2. And put your Redirection in Application_Error in Global.asax.
public void Application_Error(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
app.Server.Transfer("~/Error.aspx?ErrorID=" + errorId,true);
}
Point 3. Also check if your SessionStateis set properly in IIS too.
Details are on MSDN to enable sessionstate
Hope this helps..!!!
From what I understand, Server.Transfer sends the content of another page to the client rather than the requested content. If that is the case, then I am wondering if it does not have something to do with applying a master page to the error page? I had a similar error years ago with earlier technology and it turned out that the master page did not like what I was trying to do.
I hope this helps at least point to a solution.
Here's what the problem is:
If there is a page render exception (ex. "File Not Found") then Server.Transfer screws up the session. This has something to do with it being called during the page render.
As long as you are not appending headers before the error occurs, Response.Redirect will work just fine; if you are, however, using Response.AppendHeader then Response.Redirect will not work during a page render.
Try using HttpContext.Current.RewritePath instead. That should fix all these problems. For whatever reason, RewritePath() does not care that the page hasn't finished rendering.
why not just use customErrors in web.config to do the redirect?
<customErrors mode="Off" defaultRedirect="~/Common/Error.aspx">
<error statusCode="403" redirect="~/SM_AccessDenied.aspx" />
<error statusCode="404" redirect="~/Common/FileNotFound.aspx" />
</customErrors>
I had the same problem in a different context a while ago. I don't know if it is your case, but if you're using IIS7 on Windows 2008, in addition to setting enableSessionState=true in your web.config, you have to put your modules inside the <system.webServer> section, instead of <system.web>. Changing this little thing solved it for me.
Why don't you try like this:
The Server.Transfer method also has a second parameter—"preserveForm". If you set this to True, using a statement such as Server.Transfer("WebForm2.aspx", True), the existing query string and any form variables will still be available to the page you are transferring to.
So I think doing like this your session will not expire.
Server.Transfer("~/Error.aspx?ErrorID=" + errorId,True);
The error you are encountering is because you are using a query string parameter. Per the msdn docs
However, the path parameter must not contain a query string, or ASP returns an error.
http://msdn.microsoft.com/en-us/library/ms525800%28v=vs.90%29.aspx
Its about 3/4 of the way down the page just above Requirements.
Even though the docs here are mentioning asp. and not asp.net, keep in mind the session state is a feature of IIS and is handled before asp.net is ever called.
#user2110845 : I had faced similar problem few months ago. the problem was with having an underscore in the website name. We were deploying a website in IIS with two different host names(adding two entries through the 'Edit Bindings' option on the website). The host names provided were abc_ts, abc_is. When the underscore was removed then the session problem got resolved.
It seems there are certain characters not allowed in a website host name. Check if that is your problem.
I found the answer here : link (check 'update 2' in the article)
You don't mention what version of ASP.NET you are using, but there were some changes between 2.0 and 3.5 in how unhandled exceptions bubbled their way up through an ASP.NET web app and then IIS.
Among some other possibles, while you are clearing the error you are not setting Context.Response.TrySkipIisCustomErrors = true; While this particular flag could have nothing to do with your issue (and is only available for 3.5+), it also could help deal with what is potentially two error pages behind the scenes that are obscuring the real issue. Regardless, it'll save you a lot of grief (at least if you are running 3.5+) with other potential issues. Check out two posts I wrote several years back that may be helpful: while they don't cover session handling, they do cover the multiple song-and-dance routines I had to follow to get proper 500 and 404 handling in various versions of ASP.NET. It's possible you will run into something that will get you further ahead, if not all the way there.
http://www.andornot.com/blog/post/Errors-Sending-the-Right-Message-(Redux-Covering-ASPNET-3540).aspx
http://www.andornot.com/blog/post/Errors-Sending-the-Right-Message.aspx

inline to handle url redirect

I am migrating a site from siteA.domain.com to siteB.domain.com. All the page paths remain the same. The problem is it's a gradual migration, and not every path is being migrated at the same time. So what I need to do is check the path the user is going to, and if it's a member of a list of migrated sites, then redirect the user from siteA.domain.com/path to siteB.domain.com/path
I was hoping to add in-line c# code to the master page. Any thoughts/examples of this?
I believe the correct way would be to add some routes to the Global.asax.
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("home",
"home",
"~/Home.aspx");
}
The above code will let you type "http://mysite.com/home" and it will redirect to the Home.aspx page. You could redirect to http://myothersite.com/Home.aspx instead of using the ~, or relative path.
You can add routes for each and every page that you have in some master list.
I would have a list of address in your config that have been migrated, then in the page_load of the master page check the current url (on of the properties in Request.Url I can't remember which) and see if it is the list from the config.
Simple, but quite often the simple way is the best. Plus if it is a temporary thing there is no point wasting time doing anything complex.
Any reason not to use IIS for the redirect? SO Question - How to redirect a URL path in IIS?
Create an IHttpHandler that intercepts all incoming requests and redirects appropriately.

Sitecore 500 Error Logging / Alerts

Problem
Currently, I'm looking to serve a custom 500 error page as well as log and alert a web master about the condition that was hit (What URL, stack trace, timestamp, etc.).
I tried defined custom http errors under system configuration, but the error pages were not hit.
I am able to handle 404s and their related errors (layoutnotfound).
Question
Should I intercept the context in global.asax to handle the 500 errors and return a custom page? Is there another way with Sitecore to achieve what I'm looking for?
Mainly, I'm looking for best practice of logging / alerts for 500 errors with Sitecore
Try using ELMAH.
Here is an article on using it with Sitecore.
Elmah is great and does a good job. You can also use log4net to log exceptions. All you do is add an application_error method in global.asax and you can track all the errors that occur. You can also add different appenders and can log messages in a log file, database and email them.
Here is the code that logs the error and includes some additional information like url and Current sitecore item:
private static readonly ILog log = LogManager.GetLogger(typeof(Global));
protected void Application_Error(object sender, EventArgs e)
{
if (Context != null)
{
Exception error = Context.Server.GetLastError().GetBaseException();
log.Fatal(
GetErrorMessage(), error);
}
}
private string GetErrorMessage()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Application_Error: Unhandled exception has been occured.");
try
{
sb.AppendLine("Current Request: " + Context.Request.RawUrl);
Sitecore.Data.Items.Item currentItem = Sitecore.Context.Item;
if (currentItem != null)
sb.AppendLine(String.Format("Current Item ({0}): {1}", currentItem.ID, currentItem.Paths.FullPath));
if (Sitecore.Context.Database != null)
sb.AppendLine("Current Database: " + Sitecore.Context.Database.Name);
}
catch { } // in no way should we prevent the site from logging the error
return sb.ToString();
}
If you want an easy solution I would recommend going with Elmah. If you want to have more control and more logging options you should go with a custom log4net solution.
I tried defined custom http errors
under system configuration, but the
error pages were not hit. I am able to
handle 404s and their related errors
(layoutnotfound).
On that particular point...Be aware that custom errors behave differently when accessed locally. Also, by default you need to use physical files (not sitecore pages) for these pages. You need be aware of IIS behaviour when returning status codes over 200 and how it is dependant on the configuration within web.config and (if running in integrated mode) the section. In particular, see the flow chart half way down the first link below.
http://learn.iis.net/page.aspx/267/how-to-use-http-detailed-errors-in-iis-70/
http://www.iis.net/ConfigReference/system.webServer/httpErrors
http://msdn.microsoft.com/en-us/library/ms689487(v=VS.90).aspx
You might also want to change the RequestErrors.UseServerSideRedirect setting to "true" to provide better http responses without redirects.

Categories

Resources