I am trying to do something fairly simple but seems like a near impossible task with the SharePoint API.
My SharePoint Data Structure is like:
-Folder
--- Sub Folder
--------Item A
--------Item B
--------Item C
--------Item D
For some strange reason you cannot access the Folder and subfolders in the hierarchical manner that you would expect! When I iterate over the List it will return all the items ignoring the hierarchical structure (i.e. it will return everything in the list). Worse, you don’t event know if the item is a Folder or not in order to manage the structure in code.
Now I am writing Custom Objects to make the SharePoint object model a bit more meaningful and group data in the hierarchical that I expect. I'm planning for my SharePoint items to be mapped as follows:
public class Folder
{
public Folder Parent {get; set;}
public Folder Root {get; set;}
public IList<Item> Items {get; set;}
}
Has anyone done something similar or how did you manage this limitation in SharePoint?
Is there any lessons learned and things to watch out for if I start mapping to my custom object model?
EDIT:
My final solution was too loop through the folder starting from list.RootFolder.SubFolders.
var query = from SPList list in Utils.GetList(webRelativeUrl, listName)
from SPFolder folder in list.RootFolder.SubFolders
where folder.Name.ToLower() != "forms"
select new Folder //Custom Object
{
Name = folder.Name,
Children = (from SPFolder subFolder in folder.SubFolders //Further looping of sub folders
select new Folder
{
Name = subFolder.Name,
Items = (from SPFile file in subFolder.Files
select new Item
{
//Mapping code omitted
} ).ToList()
}
{)
}
return query.ToList();
No, you really should not create your own objects to obfuscate the SharePoint object model. Essentially, the SharePoint OM reflects the way objects are stored. I.e. lists go in a single database table, not into folders like a file system.
The best way to go forward (based on pretty painful experience) is to grind your teeth and go with the way SharePoint does things.
In this case it is not to use folders in the same way you would in a filesystem. It is easier to "tag" your list items/files with metadata and use grouped views to show it to users than it is to use a folder structure.
Often a folder structure (on disk) is used as a surrogate for metadata (e.g giving a file implicit metadata by putting it in the BusinessGroups/Marketing folder instead of tagging it with a "Marketing" value for BusinessGroup.)
SharePoint is too large and unwieldy to "fight" in the way you propose. Go with the flow.
What I did was to check if an item's parent was the list I was currently traversing, and work from there. The
SPQuery
class may also be a good way to go. Best of luck!No, just use the SPQuery class to fetch items from a single folder. This article explains how.
For your specific purpose, what is wrong(*) with getting the SPList.RootFolder from the list and working from there, recursively traversing the subfolders and items in each folder?
(*) Ignoring the performance aspect here...
To add to Lars' answer (which is the right answer), if you feel the need to change the object model, try and solve your problem with an extension method. I've been doing that to some success,