views:

157

answers:

2

I'm currently building an app that will parse all of the Audit entries in a site collection and send out a pretty email to users.

My problem is that the emails should be based on a particular web (essentially an email summarizing the changes that happened to each subsite). Apparently, there is no information in the SPAuditEntry object about the web it came from except for the DocLocation property.

This means I can get any of the following DocLocations (ItemType = Document, Event = Update):

  • sites/MySiteCollection/Documents/This is a test.doc
  • sites/MySiteCollection/Reporting Templates/audit.xml
  • sites/MySiteCollection/Lists/Reporting Metadata/1_.000
  • sites/MySiteCollection/MySubSite1/Lists/Announcements/2_.000
  • sites/MySiteCollection/MySubSite1/Template Documents/SampleTestEmail.doc

I'm thinking I can probably figure out the web from the URL by using SPSite.AllWebs.Names if I have to.

Q: How do I figure out which SPWeb a particular SPAuditEntry comes from?

A: 

I might have something (very crude), but it kinda depends on how deep your sub webs are nested. Are they just 1 level deep (i.e. site/web1, site/web2 or site/web1/web1_1 etc.). And have you looked if the SPAuditEntry objects have a ScopeId in their EventData xml? Found an article that describes kinda the same as you that uses the ScopeId from the EventData xml to do some matching:

Article

Also, the following post describes using the ItemId (guid) in an SPSiteDataQuery to retrieve the item, then uses the resulting data (WebId and ListId) to open a specific web / list. Might be a bit inefficient to retrieve an item at a time but it something...

Post

Colin
They will probably only be one level deep. I will check out the links.
Kit Menke
I decided to go with my AllWebs.Names approach (using that array and then parsing the DocLocation url to find the SPWeb). Submitting a query for every item seemed like overkill to me, but thanks for giving me some other options!
Kit Menke
A: 

My solution is outlined below in pseudocode:

  1. Get the collection of all web names in my site collection: _allWebNames = site.AllWebs.Names;
  2. Since I only care about the top level SPWeb's inside the site, I parse the SPAuditEntry.DocLocation to get the possible web name. (Ex: will return "MySubSite1" out of "sites/MySiteCollection/MySubSite1/Lists/Announcements/2_.000")

    string webName = GetPossibleWebName(SERVER_RELATIVE_URL, docLocation);

  3. Then search my array to see if the web name matches.

    index = Array.BinarySearch<string>(_allWebNames, webName, new ServiceSiteNameComparer());

  4. If I find a match, then I can using SPSite.OpenWeb(string) to open the web and get the ID.
Kit Menke