5

I'm stuck with a problem here that leaves me stupefied. I am writing an HttpModule which examines the URL of all HTTP requests in order to log which users have downloaded each document in a document library. Everything works the way it should when logged into the server machine. However, when logged on from another machine in the network, it appears that occasionally, HTTP isn't used at all.

Logging all HTTP requests, when logged into the server I get a request for the URL like http://portal.customer.local/reports/Reportslib/xsht2.xlsx whenever downloading a document. When viewing the documents from another computer in the network, this request usually appears. When viewing an Office document, however, there is sometimes a request for http://portal.customer.local/reports/_vti_bin/cellstorage.svc/cellstorageservicentlm instead. I figured this might be some sort of service function, and sure enough, when examining the header of this request, I find the field

SOAPAction=%22http%3a%2f%2fschemas.microsoft.com%2fsharepoint%2fsoap%2fICellStorages%2fExecuteCellStorageRequest%22

So I'm guessing that SOAP is somehow used to to retreive the document, maybe if it has been cached somewhere or there is some special connection to the Office application involved.

So, two-part question:

(1) Does anyone have an idea what's really going on here? Is there a way to work around it?

(2) There has got to be some easier way to do this. My objective is just to log the document name and username whenever a document has been downloaded. Is there something I'm overlooking?

class FileDownloadedEvent : IHttpModule
{
    public void Init(HttpApplication context)
    {
        // Register event handler to be called after every page request
        context.PostAuthenticateRequest += ContextPostAuthenticateRequest;
    }

    static void ContextPostAuthenticateRequest(object sender, EventArgs e)
    {
        var app = sender as HttpApplication;
        if (app != null)
        {

            string requesturl = app.Request.Url.ToString();


                    // Inspect request url to see whether it's a request to download a document from the document library
                    if (requesturl.StartsWith(Utils.reportsLibraryUrl) && (!requesturl.Contains(".aspx")) && (!requesturl.EndsWith("/")))
                    {
                        SPWeb web = SPContext.Current.Web;

                        String fileName = requesturl.Substring(Utils.reportsLibraryUrl.Length);

                        // Call event handler action to register downloaded document
                        web.AllowUnsafeUpdates = true;
                        EventHandlerActions.documentDownloaded(web, requesturl, fileName);
                        web.AllowUnsafeUpdates = false;
            } 
        }
    }


    public void Dispose() { }

}

2 Answers 2

4

You could enable audit on the 'View' events of the SPListItem. You can then query with something like:

SPSite site = ...
SPListItem item = ...
SPAuditQuery query = new SPAuditQuery(site);
query.RestrictToListItem(item);
SPAuditEventType[] eventTypes = new SPAuditEventType[] { SPAuditEventType.View };
SPAuditEntryCollection auditLog = site.Audit.GetEntries(query);
1
  • Thanks a lot, guys. This solves my problem in a reasonably tidy way. Both answers are good; I'm awarding to @Andy because this is what sent me down the right path. Commented Jun 14, 2011 at 12:34
8

It sounds like you are reinventing the wheel. SharePoint ships with an Auditing infrastructure, which although flawed, will probably give you what you need.

Have a look at the following:

  1. When using WSS3 or SharePoint Foundation you don't get a user interface so you will need to set and query it programmatically. (2007 article, but it works the same in 2010)
  2. Using MOSS 2007 or SharePoint Server 2010 you get some built in functionality. Reporting can be a bit buggy though.
  3. Get a 3rd party component that does it all for you, regardless of your SharePoint environment and without all the bugs.

Please note that the link to the 3rd party component points to a product I worked on so the usual disclaimers apply.

4
  • Thanks for your input. If I'm not overlooking anything, the built-in auditing reports don't give any information about which users have viewed each document. I'll look into the third-party option, but it is probably much more comprehensive than what we need. Commented Jun 13, 2011 at 10:24
  • +1 for using SharePoint's Auditing - but you may have to have an HTTPModule as well for auditing views of non-current versions of documents...
    – Andy Burns
    Commented Jun 13, 2011 at 10:25
  • 1
    @Andy, Views of non-current version of documents has (finally) been fixed in one of the more recent CUs. Commented Jun 13, 2011 at 10:35
  • Excellent. It only took them years! Good to know, thanks.
    – Andy Burns
    Commented Jun 13, 2011 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.