All about the Strategy, Design, Customisation, Deployment and Development of SharePoint and its related Technologies

  Administration   All Me!! Baby!!   BDC   Book Review   Business   CKS   Conferences   CQWP   Development   Duffer Moments   Email   Errors   Family   Fixes   General   Groove   How To   How To Code   InfoPath   iPhone   IRM   Longhorn   Lotus Notes   Migration   Mobility   Office System 2007   Personal Projects   Powershell   Records Management   Search Server   Security   SharePoint   SharePoint 2010   Silverlight   SQL   Tech Ed 2008   Testing   Vista   VSTO   WSS   XSL

[03/06/2009] MOSS 2007 – Capture direct view clicks
 
Categories: Development, How To Code, Office System 2007, SharePoint
 

If like me you have worked on a mix of intranet, extranet and internet you will have no doubt been asked about capturing direct file clicks. So an example would be you wish to know the top PDF document that is being clicked on your public facing site. Out of the box SharePoint does its best with the usage analysis framework but does not capture everything that you may need. In this post I will show you how to use custom code to capture specific file type links and log them to a list. Firstly let's create the list to store the values, to do this I am going to create a content type and then associate this with a custom list.

Now have our new content type albeit a very basic one, we can then create our new list and associate accordingly.

So to make this work we could use some code that resides within the "Global.asax", I like this approach as it means you do not need Visual Studio to make changes and they can be done on the fly, however this is not the best approach. For this we will create a custom "HttpModule" that we will register within the "web.config". So to begin let's create a class library project in Visual Studio and ensure it inherits from the "IHttpModule" class. I am going to name my class "CountDirectLinks.cs" and then create a utility class for any functions etc that I need and call that "CountDirectLinksUtilities.cs".

So firstly ensure that we are inheriting correctly and have the correct namespaces for this to work.

We now need to create the base methods for capturing the relevant events. To do this we will use the following code:

This initialize method attaches to the current context and calls the "AuthenticateRequest" method. This allows us to intercept anything that happens after a user has been authenticated. We could use other methods if needed such as "BeginRequest"; this would capture anything before it was authenticated. In our case we wish to get the clicked links when someone has been authenticated. Our code should look like the following:

Now part of this solution was to allow the Administrator to specify the file types that they wish to capture and log. To do this we will simply create the following "appSettings" within the web.config. We will also add two extra ones for the root site URL and the list name that we are to log to. This could be done differently but I chose this for this example.

The list of file types will simply be a separate list that we will then read into the HttpModule and use accordingly. So firstly let's create our code for inserting the content into our list. We need to create the method and then get the values from the "AppSettings" within the "web.config" using the "ConfigurationManager" namespace.

We then add the following code to get a SPSite and SPWeb object.

Now we can add our code that will create the new list item.

Notice that I am calling a utility method called "GetFileName" this is because when I grab the URL I get something like this:

http://intranet/Dev/Shared%20Documents/myDocument.pdf

I would need to parse this out so I would get just the name of the file instead. Even though this would work I felt it would be better to call a function that would give me access to the metadata fields that were associated with the actual file. This would then allow me to extend the solution further by getting other details about the file rather than just the URL. For this example I get the actual name of the file as shown in the library or list.

This method is a re-hash of the one I used in my Search API posts a while back. The code should be similar to this:

So now we have our method created that will actually insert to our logging table, now let's modify the "AuthenticateRequest" method so it reads the file types and then inserts the log as needed.

As you can see this grabs the current "HttpApplication" which comes from the initialize event, grabs the file types as an array and parses them and inserts the log when needed. Okay so now we have built it, let's built and deploy. In my case it creates a DLL, which I add to the GAC (development box), and then add the following entry to the "HttpModules" section of the "web.config" file.

So test this we can upload some files into a library and then access them. The following screenshots is the process I took:

If we now look in the custom logging list we can now see two entries for the viewed files:

If you remember we are only logging PDF, PNG and DOCX file extension but this could be changed.

As you can see with a little customization we could capture all kinds of content about the current user or visitor accessing the site. In the next post we will extend it to capture more information and events through the system. J

 

 
14 Comments
 

Comments

Wednesday, 3 Jun 2009 01:01 by Jeremy Thake
This is great! Awesome way to track these things without relying on 3rd party alternatives.

Wednesday, 3 Jun 2009 05:46 by Estyn Edwards
What is the performance impact of doing something like this? In the past we've turned on auditing in order to record who views what files. The down side of this is that your audit logs get very big very quickly so you need to have a strategy to deal with that.

Wednesday, 3 Jun 2009 08:32 by Liam Cleary
Hey Estyn, As far as performance goes this would need to be tested within a live web site or intranet etc. As it is an HttpModule there should not be that much overhead. MSFT do use them as well within SharePoint. The auditing works well however it does east the disk space pretty quick. From some base tests I have done performance does not seem too much of an issue. Would be great to hear from anyone who agrees or disagrees. Liam

Thursday, 4 Jun 2009 08:41 by Xidan
Hi, Liam, I have a question unrelated to this particular post, but need some advice. I tried the contact me form but the email didn't send. Please email me directly regarding my question. Thanks. I'm using the CKS's EBE to creating a blog site. My problem is that the comments do not show for anonymous users. They can post comments, but not comments for a post shows up and the comments count is zero. I tried to give the iusr user account full or contribution permissions on the Comments list, and even tried to uncheck the "Enable securing system pages" under the blog setting, none worked. Would you be able to point me to the right direction in resolving the issue? Thanks in advance for all your help! Xidan

Friday, 5 Jun 2009 12:38 by Sandeep
Great.. do you made the code available by any chance ? thanks in advance

Saturday, 6 Jun 2009 05:53 by Sandeep
i think u shud be usign context_PostAuthenticateRequest rather than context_AuthenticateRequest , also are u not capturing user identity , who downloaded it

Monday, 8 Jun 2009 09:12 by Liam
Hey Sandeep, This code is only an exmaple of what you could do. In the next post I will modify it slightly to capture more details and use a few different pipeline events. Thanks Liam

Monday, 8 Jun 2009 09:18 by Liam
Hey Xidan, I did not get your email address. Try using the contact me link again. Should be working now. Thanks. Liam

Tuesday, 9 Jun 2009 09:01 by Michael
Hello You contact form does not work. Every attempt to contact you leads to the message "Failure sending mail.". Michael

Thursday, 11 Jun 2009 04:06 by Michael Bürschgens
Hi Liam Your Contact form is defective. Every time I try to contact you, I get the error message "Failure sending mail.". Michael

Tuesday, 16 Jun 2009 10:22 by Liam Cleary
Hey, the contact me form should now be working. It was an exchange error. Thanks. Liam

Wednesday, 17 Jun 2009 05:23 by Sailesh
Hi Liam, Was searching for Sharepoint MVPs and came across your blog. I have a question with regards to a requirement to build a public facing website to do mainly with autorised access and document collaboration and workflow. My understanding of SharePoint is that it can be used only for the intranet. Is it possible to build a public facing website and integrate it with sharepoint model for document access and workflow and what other products would I need to build the above application

Thursday, 18 Jun 2009 11:18 by Liam Cleary
Hey Sailesh, Use the contact form above and drop me your details. We can chat about this then. SharePoint can be used for either an Intranet or Public Facing site and use both elements in one site. Lets chat. Liam

Monday, 29 Jun 2009 12:15 by Tobias Zimmergren
Sweet Liam, this really kicks. I was doing something like this myself a while back, but had to let it go due to other more critical aspects. Great article, keep it up!

Name:

URL:

Email:

Comments: