Pergunta

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() { }

}
Foi útil?

Solução

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);

Outras dicas

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top