Bryant Likes's Blog

It's all about WebData

Recent Posts

Tags

News


  • Windows Live Alerts
    View Bryant Likes's profile on LinkedIn

    Me

    Get Microsoft Silverlight
    by clicking "Install Microsoft Silverlight" you accept the
    Silverlight license agreement


    The posts on this weblog are provided "as is" with no warranties and confer no rights. The opinions expressed herin are the personal opinions of the individual authors and do not represent the views of Avanade in any way.

Community

Email Notifications

Archives

Extending SharePoint using Global.asax

Have you ever wanted to do stuff with SharePoint sites that webparts just won't let you do? Here are a few things that I wanted to do in SharePoint that I knew I couldn't really do with WebParts or custom pages.

  • Better stats - the built-in stats are ok, but I want some better stats.
  • Register Users - I want everyone to have access to the site, but I would like to collect a little information about them before I give them access.

For this article I will just tackle the task of getting better stats about SharePoint usage, but you can easily apply the methods I use to do all kinds of things in your SharePoint application.

First off, you will need to do a little background reading on Global.asax (if you aren't already familiar with it). The Global.asax file allows you to write code against events that happen within an ASP.Net application. SharePoint is no different so you can write custom code and stick it in the Global.asax file and gain more control over your application.

Below is a quick and dirty solution for capturing information about how people are using your SharePoint site (or portal). Of course you can use the built in stats, however, I personally find those stats to be somewhat limited. The method below captures the URL the person went to, the timestamp of the request, and the UserID. What you can do is to add this code to a file called Global.asax and place it in the root directory of your site.

<%@ Application ClassName="Globals" language="c#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web" %>
<SCRIPT language="C#" runat="server">
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
  try
  {
    using (SqlConnection cn = new SqlConnection("[Your Connection String]"))
    {
       cn.Open();
          
       SqlCommand cmd = new SqlCommand();
       cmd.Connection = cn;
       cmd.CommandText = "Hit_Add";
       cmd.CommandType = CommandType.StoredProcedure;
       
       HttpContext ctx = HttpContext.Current;
       
       cmd.Parameters.Add("@Url", SqlDbType.VarChar, 256).Value = ctx.Request.Url.ToString();
       cmd.Parameters.Add("@UserID", SqlDbType.VarChar, 50).Value = ctx.User.Identity.Name;
       
       cmd.ExecuteNonQuery();
       
       cn.Close();
    }
  }
  catch (SqlException)
  {
 // Eat the exception so that the site is still usable
 // even if the stats go down from some reason.
  }
}
</SCRIPT>

Before you can use the script you will also need to create a table and a stored procedure to populate the table. Below is the SQL script to create both. You will need to put them in a custom database (I would not recommend putting them in one of the SharePoint databases).

create table [Hits] 
(
 Url varchar(256) NOT NULL,
 UserID varchar(50) NOT NULL,
 Timestamp datetime NOT NULL 
)
go
create proc Hit_Add
(
 @Url varchar(256),
 @UserID varchar(50)
)
as
 insert into Hits values
 (@Url, @UserID, getdate())
 
go

That's all there is to it. The AuthenticateRequest Event gets fired each time the user makes a request to the site. You make the call to the database here because in the BeginRequest event the user hasn't been authenticated yet. I'm not sure but I believe this is different from normal ASP.Net applications due to the way SharePoint handles the request.

I'm sure you can think of many other ways that this will be useful. I'll be looking forward to your comments and suggestions.

Posted: 05-11-2004 6:03 PM by bryantlikes | with 36 comment(s)
Filed under:

Comments

TrackBack said:

# May 12, 2004 10:19 AM

TrackBack said:

# May 13, 2004 2:28 PM

bryantlikes said:

i'm place youre cod to my Global.asax file, create the table and procedure, but i have the Server Error in '/' Application. Runtime Error
# May 13, 2004 11:10 PM

bryantlikes said:

Make sure that your connection string is correct. You cannot use integrated security so you will need to set a username/password. When you do this make sure that SQL Server is setup to use mixed authentication.
# May 14, 2004 7:25 AM

bryantlikes said:

can you show me example of the connection string ?
# May 23, 2004 8:56 PM

bryantlikes said:

I did everything the way you described but none of the events in my global.asax get triggered. Is there anything else I should do to make SharePoint use this global.asax?
# June 4, 2004 8:44 AM

bryantlikes said:

Mario: What kind of security do you have on the site? Also, I would try commenting out the try/catch section so that you can see if you're missing the SQL error.

Denis: Here is the format I'm using:
DATABASE=[DB Name];SERVER=[Server];UID=[User Name];Password=[Password];
# June 8, 2004 6:14 PM

TrackBack said:

# July 7, 2004 3:01 AM

TrackBack said:

# July 7, 2004 3:03 AM

bryantlikes said:

Everything ok, adds all in the DB.
Also cab (signed and ok) with stsadm installed. All successfully.
BUT
When in SharePoint dragging the webpart to the page (after dragging and auto refresh of the page) nothing is there :-(

Can you help me out?
# August 18, 2004 1:03 PM

bryantlikes said:

This is a perfect example of how NOT to implement a Sharepoint Statistics tracking piece. Why not use some OOP techniques and implement the IHttpModule interface to accomplish this task. The resulting module would leave the original SPS global file intact, while delivering a truly elegant solution.

P.S.
You are an IDIOT!!

# September 27, 2004 10:20 AM

bryantlikes said:

I fail to see what advantages you would gain from using an OOP technique. Leaving the global file intact was not one of my prime concerns, nor was an elegant solution. I simply wanted to enable some logging into a database (which I accomplished in about ten minutes).

If this means I'm an idiot, oh well.
# September 27, 2004 1:44 PM

bryantlikes said:

Boy,
They give the MVP status away to anybody.
# September 28, 2004 8:10 AM

bryantlikes said:

But you can analyze log of iis and get same info ;)
Without creating gloabal.asax, base and other.
# October 18, 2004 9:32 AM

bryantlikes said:

True, you could analyze the log to get the stats. You wouldn't be able to show who's online though, unless you analyzed the log quite often. You also run into issues if you have multiple sites and/or if you have multiple front-end sites sinc e you have to analyze multiple logs on multiple machines.
# October 18, 2004 1:09 PM

Ryan said:

Just came across this post and it implemented perfectly, when remembering that a stored procedure needs to have execute permissions granted to the user provided in the db connection.  

On a separate note, people that call other people idiots for working implementations usually tend to be the bigger idiot.  I'm pretty sure I, and probably every other developer out there, has worked with (at one time or another) the person who put that post up.  Rude * 100.
# March 7, 2006 6:13 AM

Ryan said:

i agree with the other Ryan, it is very rude to call others idiots, especially if they are trying to benefit others, however i have a problem in sharepoint i need solving, is there a way to know the number of times a document in a document library has been opened (with/without modification, i.e used) by a specific person in an interval of time? if would prefer someone would could give hints about it without going to third party programs, i.e using sharepoint sdk if possible (i have already tried with event handlers but no luck ) :(
Any ideas?
cheers,
# April 26, 2006 9:30 AM

krausyd said:

could any of you help me? i don't know where i can find the global.asax of my site....
thanks
# May 18, 2006 11:54 AM

Bryant Likes said:

You need to create one.
# May 19, 2006 10:03 AM

John said:

Good post.  I was looking around to see if you could run scripts in the Global.asax file in Sharepoint (since it's disabled in the ASPX pages).. guess this answered my question!  ;)  

# October 24, 2006 5:15 PM

Joydeep Banerjee said:

You have given a very good example of who's online web part Bryant..

# April 26, 2007 3:26 AM

Joydeep banerjee said:

How do i delete the users when they log out or close the browser? Can anybody help?

Thanks in advance

# May 24, 2007 4:24 AM

Kevin Cornwell said:

Aside from using Application_AuthenticateRequest, is there another function or function that I can use so that it only triggers once per page.  I am getting a lot of hits per page (i.e. .jpg's, .css's, etc.).  I would prefer a single log entry per page per user.  

Thanks a lot,

Kevin C

# August 6, 2007 2:22 PM

Bruce said:

Hi I have implemented this on a sharepoint intranet/extranet (without webapart - data collection only at this stage). Works fine until i try to reload the extranet view. The site will not load and shows "An unexpected error has occurred. " I'm guessing this has something to do with the domain\user specified in the stored procedure? - as the extranet is forms authentication only. Any ideas would be appreciated.

# January 16, 2008 4:21 PM

Keith said:

I can not seem to get the connection to the Db to work. I setup the tables and stored prcedure and put the changes in to the global.asax file. But nothing gets put in to the DB. I have verified my sql connection string is correct. Is there anything special I have to do for SQL Express 2005. I am using Windows SharePoint services 3, and have applied all the patches.

Thanks in Advance

Keith

# February 15, 2008 12:41 PM

Keith Davis said:

I had one heck of a time making the connection string work. So I am posting what I did here to hopefully help someone else. I admit I am new to this and still learning.

First if you use SQL2005 Express, remember it comes totally locked down. There instructions all over web about unlocking it.

Here is the connection string format I used:

SqlConnection cn = new SqlConnection(@"Data Source=.\SQLEXPRESS;User

ID=MyUsername;Password=MyPassword;Initial Catalog=Test;Integrated

Security=False;User Instance=False");

I really hope this helps someone.

Keith

# February 29, 2008 8:12 AM

Megan said:

Does anyone know if it is possible to accomplish this using a list/table on the sharepoint site?

Thanks for the post.

# April 29, 2008 2:04 PM

Jeff said:

Hi,

I tried ur code, but I got the runtime error.  P.S I have a correct Sql string.

Thanks

# June 12, 2008 2:15 AM

Ultracet. said:

Ultracet.

# June 28, 2008 1:08 AM

Lexapro. said:

Celexa lexapro. Lexapro side effects. Side effects of lexapro. Lexapro. Lexapro medication adverse effects.

# July 27, 2008 10:40 AM

Satish said:

How do i delete the users when they log out or close the browser? Can anybody help?

Thanks in advance

satish (bflsrc@yahoo.com)

# August 19, 2008 12:02 AM

Matt said:

Be very careful doing this.  Sharepoint (WSS 3.0 / MOSS 2007) overrides the Global.asax file to inherit from Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication rather than System.Web.HttpApplication.

If you use code behind (or code in the markup) you should make sure to perserve that inheritance.  For example, the top of your markup should look like:

<%@ Assembly Name="Microsoft.SharePoint"%>

<%@ Application Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" Language="C#" %>

or (if using code behind)

<%@ Assembly Name="Microsoft.SharePoint"%>

<%@ Application Codebehind="Global.asax.cs" Inherits="MyAppName.Global" Language="C#" %>

if your using code behind, your class should be declared like:

public class Global : Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication {

//Code goes here

}

# September 27, 2008 9:38 AM

Nadian said:

Hi,

Thanks for your great solution,I implement this Code and now,every things are OK,But my problem is that I have a web application in Form Based Authenticatinon and an extended web application in Windows based.I just see the form based users,what can I do to view all users?

# February 28, 2009 12:48 AM

beaurfunrearf said:

# May 31, 2009 12:21 PM

beaurfunrearf said:

# June 1, 2009 10:10 PM

Pesbiseelplaw said:

<a href=baronhaitvideo.ru/.../skachat-porno-absolutno-besplatno.html>%D1%81%D0%BA%D0%B0%D1%87%D0%B0%D1%82%D1%8C порно абсолютно бесплатно</a>

Будто- В общем-то они люд вольные, затем Клыков произнёс, да-с.

# June 4, 2009 6:01 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)