0

SharePoint 2013 on premises.
I'm executing a query on audit log with restriction to a specific list and user.
I'm getting results and I need to get the list item ID using the guid in the results and insert it into list of string.
My code:

    Public Function GetAllReadItemsAudit(lstRelativeUrl As String) As List(Of String)
    Dim lstStr As New List(Of String)

    Dim listUrl As String = lstRelativeUrl
    Dim list As SPList = Nothing
    Try
        Using site As New SPSite(lstRelativeUrl)
            If site IsNot Nothing Then

                Dim webUrl As String = listUrl.Substring(site.Url.Length)
                Dim formsPos As Integer = webUrl.IndexOf("/forms/", 0, StringComparison.InvariantCultureIgnoreCase)
                If formsPos >= 0 Then
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, formsPos))
                End If
                Dim listPos As Integer = webUrl.IndexOf("/lists/", 0, StringComparison.InvariantCultureIgnoreCase)
                If listPos >= 0 Then                     
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, listPos))
                Else                       
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c))
                End If
                Using web As SPWeb = site.OpenWeb(webUrl)
                    If web IsNot Nothing Then
                        Dim title As String = web.Title
                        list = web.GetList(listUrl)
                        Dim query As New SPAuditQuery(site)
                        query.RestrictToList(list)
                        query.RestrictToUser(web.CurrentUser.ID)

                        query.AddEventRestriction(SPAuditEventType.View)

                        query.SetRangeStart(DateTime.Now.AddDays(-360))
                        query.SetRangeEnd(DateTime.Now)
                        Dim auditCol As SPAuditEntryCollection = web.Audit.GetEntries(query)
                        If auditCol.Count > 0 Then
                            For Each audit As SPAuditEntry In auditCol
                                Dim ItemID As String = list.GetItemByUniqueId(audit.ItemId).ID.ToString

                                If lstStr.Contains(ItemID) Then
                                    Continue For
                                Else
                                    lstStr.Add(ItemID)
                                End If
                            Next
                        End If                           
                    End If
                End Using
            End If              
        End Using
    Catch ex As Exception
    End Try
    Return lstStr
End Function


I'm getting exception "value does not fall within the expected range" when getting here:

 Dim ItemID As String = list.GetItemByUniqueId(audit.ItemId).ID.ToString   


I've tried declaring a new variable of type system.guid and assigning it with the value I'm getting from audit.ItemId and then feeding it to function GetItemByUniqueId - same results.
Any Ideas guys?

0

Ok, found the reason for the problem and the solution.
First of all, it seems that SharePoint 2013 doesn't record events for viewing a list item. Because when you view a list item you actually open a template, the audit log has an entry for that template and not the item.
Since the template as an ASPX page, it shows in the log as document.
Solution:
Requirements:
1. Create a webpart to write custom entries to audit log.
2. Create a feature that will load this webpart into "AdditionalPageHeader".
3. Alternatively, add this webpart to your master page.
Webpart code:

    Imports System
    Imports System.ComponentModel
    Imports System.Web.UI.WebControls.WebParts
    Imports System.Web

     <ToolboxItem(False)> _
     Partial Public Class WPAuditLogEntryForListItemViews
     Inherits WebPart

      Public Sub New()
     End Sub

Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
    MyBase.OnInit(e)
    InitializeControl()
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim sPath As String = System.Web.HttpContext.Current.Request.Url.ToString
    Dim ItemId As String = HttpContext.Current.Request.QueryString("ID")
    Dim list As SPList = Nothing
    Dim listUrl As String = sPath
    Try
        SPSecurity.RunWithElevatedPrivileges(
            Sub()
                Using Site As New SPSite(listUrl)
                    If Site IsNot Nothing Then
                        Dim webUrl As String = listUrl.Substring(Site.Url.Length)
                        Dim formsPos As Integer = webUrl.IndexOf("/forms/", 0, StringComparison.InvariantCultureIgnoreCase)
                        If formsPos >= 0 Then
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, formsPos))
                        End If
                        Dim listPos As Integer = webUrl.IndexOf("/lists/", 0, StringComparison.InvariantCultureIgnoreCase)
                        If listPos >= 0 Then
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, listPos))
                        Else
                            webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c))
                        End If
                        Using web As SPWeb = Site.OpenWeb(webUrl)
                            If web IsNot Nothing Then
                                Dim title As String = web.Title
                                list = web.GetList(listUrl)
                                If list.BaseTemplate = SPListTemplateType.GenericList Then
                                    For Each item As SPListItem In list.Items
                                        If item.ID = Convert.ToInt32(ItemId) Then
                                            item.Audit.WriteAuditEvent(SPAuditEventType.View, "VIEW", (Convert.ToString(ItemId)))
                                        End If
                                    Next
                                End If
                            End If
                        End Using
                    End If
                End Using
            End Sub)

    Catch ex As Exception

    End Try


  End Sub

 End Class

Code to get all user read list items from audit log:

    Public Function GetAllReadItemsAudit(lstUrl As String) As List(Of String)
    Dim lstStr As New List(Of String)
    Dim listUrl As String = lstUrl
    Dim list As SPList = Nothing
    Try
        Using site As New SPSite(lstUrl)
            If site IsNot Nothing Then

                Dim webUrl As String = listUrl.Substring(site.Url.Length)
                Dim formsPos As Integer = webUrl.IndexOf("/forms/", 0, StringComparison.InvariantCultureIgnoreCase)
                If formsPos >= 0 Then
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, formsPos))
                End If
                Dim listPos As Integer = webUrl.IndexOf("/lists/", 0, StringComparison.InvariantCultureIgnoreCase)
                If listPos >= 0 Then
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c, listPos))
                Else
                    webUrl = webUrl.Substring(0, webUrl.LastIndexOf("/"c))
                End If
                Using web As SPWeb = site.OpenWeb(webUrl)
                    If web IsNot Nothing Then
                        Dim title As String = web.Title
                        list = web.GetList(listUrl)
                        Dim query As New SPAuditQuery(site)
                        query.RestrictToList(list)
                        query.RestrictToUser(web.CurrentUser.ID)                             
                        query.AddEventRestriction(SPAuditEventType.View)
                        query.SetRangeStart(DateTime.Now.AddDays(-3))
                        query.SetRangeEnd(DateTime.Now)
                        Dim auditCol As SPAuditEntryCollection = web.Audit.GetEntries(query)
                        If auditCol.Count > 0 Then
                            For Each audit As SPAuditEntry In auditCol
                                If audit.ItemType = SPAuditItemType.ListItem Then
                                    Dim ItemID As String = audit.EventData.ToString
                                    If ItemID.Contains("<") Then
                                        Continue For
                                    Else
                                        If lstStr.Contains(ItemID) Then
                                            Continue For
                                        Else
                                            lstStr.Add(ItemID)
                                        End If
                                    End If
                                 End If
                            Next
                        End If
                    End If
                End Using
            End If
        End Using
    Catch ex As Exception
    End Try
    Return lstStr
End Function 


This function will return a list of string containing all List item ID's that user has viewed in the past 3 days.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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