Application_OnError not always working - asp.net

I experience strange problem. We have error handling in global.asax that would redirect user on special page in case if error happened:
void Application_Error(object sender, EventArgs e)
{
.......
string pageError = "~/LastError.aspx?AfterNextClick=" + afterNextClick.ToString();
if (Request["guid"] != null)
pageError += "&guid=" + Request["guid"];
Server.Transfer(pageError);
}
Custom errors are turned off.
<customErrors mode="Off"/>
Most of the times the Application_OnError works perfectly and redirects users to the specific page, but sometimes, users are not redirected anywhere and an ASP.NET exception page is displayed.
So is there any situations in which Application_OnError in global.asax wouldn't fire?

Probably an exception is ocurring inside the Apllication_Error method. Take a closer look at the code you place in this method (where you placed ...... ).
Try placing a try/catch block in this method to debug what's going on...

Related

'A potentially dangerous Request.Form' - get the message

I have a website and someone (every time the same) is trying to send me a message through a textbox (he adds some html code where he shouldn't) and the error is raised.
Unfortunately, all I can get are messages like this one ="...chemistry http://cra..." so it`s no way that I can understand what he try to tell me.
My question is: how I can expand that text characters length limit or handle my own error so I can get the whole message?
In your Global.asax, put an Application_Error event handler in to catch all errors that occur, which should include this one.
Sub Application_Error(object sender, EventArgs e)
{
var ex = Server.GetLastError();
if (ex != null)
//Log it
}

User ID initialization on Master Page?

I have a site with multiple pages, not necessarily heirarchical. I want to query the user's identity (using AD...) whenever the user first enters the site, and create session state variables for the convenience of other pages as needed. A user could possibly enter the site without going through the default.aspx page, so I thought I'd put the code in the Master Page's code-behind.
On the assumption this is a good idea, versus some sort of static class that maintains this information, I started setting it up, but found the Master Page code-behind doesn't always seem to get fired when I enter the site. Is this a debugging phenomenon, or am I right, and the Master Page is the wrong place to put this code...?
I would recommend using the Global.asax class. You'll need to add it to your web app if it's not already there. Once you have it, you can then use the various events (session start and end, app start and end and error) to implement business logic particular to what you need exactly.
I tend to monkey around with the logged in user in the Application_PreRequestHandlerExecute event of the global.asax. This will allow you to look at the User Principle (eg - User.Identity.Name) to see who is logged in (or if they're not logged in) and do what you need to (such as set Session information for the user, etc.).
Here's a tidbit of code I've got on one .NET web app that uses the Global.asax for storing user data in the Session.
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e) {
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState) {
SetUserItem();
}
}
private void SetUserItem() {
if (Session["UserItem"] == null)
Server.Execute("~/SetSessionUserObj.aspx", true);
}
... and then the SetSessionUserObj.aspx.cs
protected void Page_Load(object sender, EventArgs e) {
string ID = User.Identity.Name;
MyUser myUser = new MyUser();
UserItem userItem = myUser.GetUserItemByID(ID);
if (userItem != null) {
Session["UserItem"] = userItem;
}
}
This is just one manner that you can go about accessing a user's identity in the global.asax. You don't necessarily have to go about doing a Server.Execute to set user data (I just did it for other reasons that fall outside the scope of this question).
Good luck.

ASP.NET Application Lifecycle - how to check configuration properties exist?

I've written a singleton class that exposes the web.config properties in a nice get property kind of way.
I want a Load method to parse the data in the config and set the public properties, and I want to throw exceptions (so they are logged in the EventLog) when a configuration key is missing or can't be parsed.
I tried placing the Load() code in Application_Start of the global.asax but then remembered this will only be run once, or until the application restarts.
Where is the best place to put code that you need to run 'everytime' your site is started/run by the user? I basically want the website to stop functioning if certain config properties cannot be loaded.
Thanks.
When you change your web.config file, the application pool is recycled. This means that the next hit will cause your Application_Start method to be called.
Altering the following files will also
trigger an immediate restart of the
application pool:
- web.config
- machine.config
- global.asax
- Anything in the bin directory or it's sub-directories
On that basis, as soon as your configuration is changed, it will be reloaded the next time a user hits the site, which should resolve the problem with the minimum number of configuration reloads, as opposed to reloading whenever a session starts for example. Therefore, you can do this (in your global.asax):
static bool configValid = false;
void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext context = base.Context;
HttpResponse response = context.Response;
HttpRequest request = context.Request;
// Redirect users to an alternate page if the current config is invalid
// I happen to pass the Url they were attempting to access in the query string
// that way you can give them a "try again" link
if ((!configValid) && (!request.Url.ToString().Contains("BadConfig.aspx")))
{
response.Redirect("BadConfig.aspx?originalUrl=" + context.Server.UrlEncode(request.Url.ToString()));
}
}
void Application_Start(object sender, EventArgs e)
{
// Load config and determine if it's valid, thus setting configValid to true/false
//
//
configValid = false;
}

Response.Redirect() ThreadAbortException Bubbling Too High Intermittently

I understand (now) that Response.Redirect() and Response.End() throw a ThreadAbortException as an expensive way of killing the current processing thread to emulate the behaviour of ASP Classic's Response.End() and Response.Redirect methods.
However.
It seems intermittently in our application that the exception bubbles too high. For example, we have a page that is called from client side javascript to return a small string to display in a page.
protected void Page_Load(object sender, EventArgs e)
{
// Work out some stuff.
Response.Write(stuff);
Response.End();
}
This generally works, but sometimes, we get the exception bubbling up to the UI layer and get part of the exception text displayed in the page.
Similarly, else where we have:
// check the login is still valid:
if(!loggedin) {
Response.Redirect("login.aspx");
}
In some cases, the user is redirected to login.aspx, in others, the user gets an ASP.NET error page and stack dump (because of how our dev servers are configured).
i.e. in some cases, response.redirect throws an exception all the way up INSTEAD of doing a redirect. Why? How do we stop this?
Have you tried overloading the default Redirect method and not ending the response?
if(!loggedin) {
Response.Redirect("login.aspx", false);
}
You can use the following best-practice code instead, as explained by this answer to prevent the exception from happening in the first place:
Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();
Since I was looking for an answer to this question too, I am posting what seams to me a complete solution, rounding up the two above answers:
public static void Redirect(this TemplateControl control, bool ignoreIfInvisible = true)
{
Page page = control.Page;
if (!ignoreIfInvisible || page.Visible)
{
// Sets the page for redirect, but does not abort.
page.Response.Redirect(url, false);
// Causes ASP.NET to bypass all events and filtering in the HTTP pipeline
// chain of execution and directly execute the EndRequest event.
HttpContext.Current.ApplicationInstance.CompleteRequest();
// By setting this to false, we flag that a redirect is set,
// and to not render the page contents.
page.Visible = false;
}
}
Source:
http://www.codeproject.com/Tips/561490/ASP-NET-Response-Redirect-without-ThreadAbortExcep

How do I crash the App Pool?

Our ASP.NET 2 web application handles exceptions very elegantly. We catch exceptions in Global ASAX in Application_Error. From there we log the exception and we show a friendly message to the user.
However, this morning we deployed the latest version of our site. It ran ok for half an hour, but then the App Pool crashed. The site did not come back up until we restored the previous release.
How can I make the app pool crash and skip the normal exception handler? I'm trying to replicate this problem, but with no luck so far.
Update: we found the solution. One of our pages was screenscraping another page. But the URL was configured incorrectly and the page ended up screenscraping itself infinitely, thus causing a stack overflow exception.
The most common error that I have see and "pool crash" is the loop call.
public string sMyText
{
get {return sMyText;}
set {sMyText = value;}
}
Just call the sMyText...
In order to do this, all you need to do is throw any exception (without handling it of course) from outside the context of a request.
For instance, some exception raised on another thread should do it:
protected void Page_Load(object sender, EventArgs e)
{
// Create a thread to throw an exception
var thread = new Thread(() => { throw new ArgumentException(); });
// Start the thread to throw the exception
thread.Start();
// Wait a short while to give the thread time to start and throw
Thread.Sleep(50);
}
More information can be found here in the MS Knowledge Base
Aristos' answer is good. I've also seen it done with a stupid override in the Page life cycle too when someone change the overriden method from OnInit to OnLoad without changing the base call so it recursed round in cirlces through the life cycle: i.e.
protected override void OnLoad(EventArgs e)
{
//some other most likely rubbish code
base.OnInit(e);
}
You could try throwing a ThreadAbortException.

Resources