Adil Baig's Tech Blog

Wednesday, January 16, 2008

Getting application Context in Sharepoint Event Handler

Hello Folks,

I hope you found some use in the Custom Query Based Lookup Field Control and the improved, fortified, Vitaminized Parent Child Control(.. I'd actually spend more time on the later, filling up the holes, then what i did in my own). Ne ways, and they lived happily ever after. So lets move on. ......

In one of our project, we had many columns in custom list that were not supposed to be exposed to business user, for e.g., if a trainee fills his end of program report (basically a list item). his tutor for the program should populate automatically. So the obvious approach that any one would go for would be:

1. Hide the column in the New/Edit item page (using sharepoint designer)
2. And populate their values (from might be other master/ reference custom list) using event handler

But things started getting messy when the event would raise error. It just dont go on the default Sharepoint error page and i get a classic ASP.NET 2.0 YSOD (yeah.. i started calling it Yellow screen of death recently!!) with a more ridiculous message which i guess most sharepoint developer must be aware( and annoyed) of : Data Source Failed to execute insert command

so lets say if i did a :



I am suppose to get a "Dude..now thats not allowed!!" on an error page that exploits the default sharepoint master.But no... it has to screw up every were doesnt it?? Believe me..."Data Source Failed to execute insert command" on a classic ASP.NET 2.0 YSOD with a stack trace is certainly not what your or mine client would like to see.

then i tried the same on a simple virgin custom list( with no sharepoint designer modification.. or master modification). every thing is perfectly how its suppose to be. Now i dint really had time to find out whether i screwed up or did the sharepoint product team??. All i wanted was that YSOD to go away (shooo..shoo)
so the simple and logical and fast solution to this was obviously :
1. Make your own custom error page with the sharepoint default master
2. dump the myError.aspx and myError.aspx.cs in the sharepoint layouts folder( thats where the actual error page also reside)
3. and on error ...redirect to my custom page and display my message there.

simple ha!!.... 1. and 2. again went smooth but then, as i said.., it has to screw up somewhere doesnt it?? to redirect i need HttpContext (n i will kick his ass who says no). but then a miracle happened.

public void ItemAdding (SPItemEventProperties properties)
{
HttpContext current = HttpContext.Current;
}

i get HttpContext.Current as a Big O' null!!! what the heck.. and i thought all the time that this guy runs 'inproc' with my w3p process. 10,000 questions all at a time started hammering ma head.. how can this be possible????. it has to run inproc!!... if it doesnt.. then is it a remote assembly call???.. how can it be???... if not.. then y is my HttpContext null???
Googled around.. blogged people.. begged people.. no one answers.. every one's with the same complain... infact i even had a thought : "enough.!!!!!............. first thing i m doin is taking an IJB to a much chilled out .NET 2.0 custom solutions floor.. yeah..(back to SqlConnection and OdbcConnection days)."

I really dont know what was going on in my mind when i tried this out as a desperate last attempt:


public class MyEventHandler : SPItemEventReceiver
{
HttpContext current;

public MyEventHandler ()
{
current = HttpContext.Current;
}
}


Hallelujah!!!!!!!! .. i get the Context. Try it in ItemAdding ...nope... try again in the default constructor !!!!!!.
Till now couldnt figure out the funda behind this, but finally i was getting my error message on my custom error page ,which, this time was even better then the default one..hahahah!!!... you dont want to show yourself up. Well, i dont need you Mr. ErrorPage.aspx... i have better one. with my full UI grooming capabilities

So the Moral of the story is ..(if you have forgotton as to from where did it all started):

plz avoid page Customization using designer if not "really" needed or might be do it in a more controlled manner( and what that would be i have no clue).
ne ways.. all you people (and i, by now, know many) who faced this ..the solution is simple!! ... initialize your context in the default constructor. will put it up on my esnips page very soon

And

Coming up next...(after 3 certifications that are queued up my ass)
A Client using Humming Bird Document management system (by oracle) with over 50,000 documents in store (and still growing ) want it all in sharepoint within 20 days.
Can this be done...(keep checkin out my space)



8 comments:

Anonymous said...

Still getting null even in the constructor... any idea?

Anonymous said...

I think it is perfectly normal that you shouldn't have access to the web context from an event handler. An event handler is not always called from a web application. You could have any application using the Sharepoint API creating, deleting or modifying items in lists. Those actions will also trigger your events and are not inside a web context. What you should do is to throw a custom exception in your event handler and then catch it inside the Sharepoint web application (http://blogs.msdn.com/jannemattila/archive/2008/02/04/catching-unhandled-exceptions-in-sharepoint.aspx) and then redirect your application appropriately. That way, other applications will also be able to handle the exception their own ways.

Adil A. Baig said...

as for the null in the context, plz enable session state in your sharepoint web.config which is by default commented out.

Coming onto the gbelzile's comment, i very well know it can run in or out of web context, i was talkin bout the case when it does run "IN" the web context, i needed to handle it on a custom page. thnx for the link you posted, i was tryin desperately to handle it in Application_Error handler in global.asax but to no avail, before i came onto this rather simple but not elegant solution, though writing a custon httpmodule dint clicked me then, really great post. thnx once again

Anonymous said...

Hi,

How to redirect to a particular sharepoint page from custom Login page's Page_Load event.I m using Page.redirect, it is throwing error - "http header already sent"

Help would be much appreciated

- sivabalan11@hotmail.com

Ali Razza said...

Thanx Adil

Nitin said...

I also have the same requirement. I have to redirect user to another list entry form. To get the reference of HTTPContext inside the Eventhandler, I try Constructor, but inside the constructor I also getting null reference.

Santhosh said...

excellent Thanks a lot ......

electronic signature software said...

This is an awesome post that we can always come back to throughout the year! Thanks for sharing.