Sometimes you can bang your head against a problem for minutes, hours, days, even weeks. And, as it turns out, the solution is really quite simple.
I've been trying to build a custom web part for a client that would simply iterate all areas of a SharePoint Portal and look for items that require Approval (they have a status of Pending). The part would then display these items to the user so they can approve the item in one place, as opposed to navigating all over the portal looking for and approving items.
I was having trouble because there are two types of content that we were interested in - Portal Listings and Document Libraries. With SharePoint, the Portal product and the standard WSS (Windows SharePoint Services) are very closely integrated, yet very different when coding against their object models. Portal Listings are only available when looking at the Portal object Area. Document Libraries are only available when looking at the WSS object Web.
To get to the Portal Listings, I tried getting a reference to the Home Area and looping through its Areas collection. The Areas collection contains Area objects that represent sibling areas. This didn't seem to give me access to all the areas and sub-areas that had been created on our Portal.
I also had to use AllWebs to gain access to all the Web objects in our Portal to get to the Document Libraries. This just didn't seem right to me.
I played around with this for days, and finally had my epiphany. I remembered some code that Jon Box had written for our Atomic.NET class. It showed using recursion to iterate a control tree of an ASPX Page.
Recursion!!!! Jeez! It's such an elementary concept. And I never considered it. So, now my code is much simpler, and it iterates everything area of the portal and looks at every list. It's perfect!
Here's a skeleton example of the code:
Private Sub iterateAllAreas(ByVal thisArea As Area, ByVal output As HtmlTextWriter)
  'Display the Portal Listings of this Area
  OutputListing(thisArea.Listings, thisArea, output)
'Areas can give you a Web   object using its Web property
  Dim thisWeb As SPWeb = thisArea.Web
  Dim lists As SPListCollection = thisWeb.Lists
  lists.ListsForCurrentUser = True
  lists.IncludeRootFolder = True
  For Each list As SPList In lists
    If (list.BaseTemplate = SPListTemplateType.DocumentLibrary) Then
      Dim docLib As SPDocumentLibrary = CType(list, SPDocumentLibrary)
      'Make sure this list allows for Approvals
      'And make sure this user has permissions to approve items in this list
      If docLib.EnableModeration And docLib.Permissions.DoesUserHavePermissions(SPRights.ManageLists) Then
        OutputDocLibItems(docLib, Replace(thisArea.Path, ":", "/"), output)
      End If
    End If
  Next
  'Recursively call this procedure for all areas and sub-areas
  For Each subArea As Area In thisArea.Areas
    iterateAllAreas(subArea, output)
  Next
End Sub
You will notice that when iterating Document Libraries, I am setting the IncludeRootFolder property to true. This is because in the OutputDocLibItems procedure, I am similarly recursively calling that procedure in order to iterate all of the subfolders of the document library. Otherwise, it would ignore all items in any subfolders that the users may have created in the doc lib.
Tuesday, August 17, 2004
Subscribe to:
Post Comments (Atom)
 
 

1 comment:
Could you please explain what the IncludeRootFolder property does exactly?
I checked MSDN, I wrote a few code samples and I cannot understand it - no matter if I set IncludeRootFolder to true or false, the RootFolder property returns the same results.
Post a Comment