Wednesday, November 27, 2013

When Should You Use Folders in SharePoint


One of the bigger misconceptions that I encounter with users is that they should NEVER use folders for their documents, images and other assets stored in SharePoint.

I have had lots of users tell me that they have read or had trainers tell them to never use folders in SharePoint.  To be honest, I usually convey the same message but make sure to prefix it with 'In most cases...'.

Why Discourage the Use of Folders?


It's not that you shouldn't use folders, it's that you shouldn't use them the exact same way you do in a standard file system.  It is typical in a file system for users to create folders that specify some properties (function, client, status, etc.) of the documents stored in them.  This allows users to easily locate the document in the file system.  In SharePoint you can use metadata to achieve the same goal and even provide a better experience to the user.

In addition to the benefits of metadata to locate a document, there are a couple good reasons to stay away from folders.

  • SharePoint's interface for navigating through documents (especially to a parent folder) is very clunky and slow.
  • There are some issues you run into when the URL path to your document is longer than 255 characters.  Each folder your documents resides in will be represented in the path.  So long folder names or very nested folders can come back to bite you.

When Should You Use Them?


Lots of Content


Based on the software boundaries and limits for SharePoint, a single list or library can support up to 30 million items with the following note:
"You can create very large document libraries by nesting folders, or using standard views and site hierarchy. This value may vary depending on how documents and folders are organized, and by the type and size of documents stored."
Without using folders, a single list or library can only support 5,000 items.  Matter of fact each folder in your library or list only supports 5,000 items so if you want to get to the 30 million mark, you will need to create a lot of folders.

If you are setting up a list or library and think that there is a possibility that it could contain more than 5,000 items, you will want to use folders.


Security


If you have a list or library that contain items that have different security requirements than the other content, folders may be used to simplify the management of the security.  Instead of securing each item individually, you could create a folder and secure that folder with the unique permissions.  Now any items you place in that folder will be secured with the same permissions as the folder (unless you set unique permissions on the individual item).

Here is a common use case:  You have a subset of documents in a library that only members of the executive team should see.  You could create an 'Executives' folder and change the permissions so only the executive team can access the content.  Now all the content administrator has to do is upload the document to that folder to secure it.

Taking the use case a step further, you could create a list / library view for the end users that strips out the folders.  This will allow members of executive team to easily find their documents without needing any knowledge of the folder structure.


SkyDrive Pro / Mapped Drives


If you don't know what SkyDrive Pro is, I'll catch you up.  It syncs a library to your computer so you can access the documents on your local machine.  It even supports offline editing.

You can also map a network drive to a SharePoint library so you can access the contents like it was a network folder.

In both these cases the documents are accessed like they are in the windows file system.  This means you don't have access to the metadata in order to easily find what your looking for.  You will just have a folder with all the documents and absolutely no organization applied to it.

If you plan on accessing libraries that contain a significant amount of files using one of these 2 methods, you will want to use folders to make the experience better.  Just remember that you should still tag the documents with the appropriate metadata.


User Adoption


This is the least technical reason on the list but still a very important one.  I have seen users shy away from using SharePoint for their documents because they had a hard time grasping a folder-less document management system.  I get it, replacing folders with libraries and metadata is not an easy concept for everyone.

When SharePoint is first being rolled out to a new set of users, I don't want to deter user adoption so I often will tell users that if they feel like they have to use folders, use them with the following guidelines.

  • The structure should only be 1-2 folders deep.
  • Keep the folder names short
  • Folders should not replace populating the the metadata for the item.


Integration


Some third party applications that you may want to integrate with SharePoint require the use of folders.  Microsoft CRM is a good example.  If you integrate it with SharePoint, it will create a folder for each opportunity.


File Name Conflicts


Just like traditional file systems, file names in SharePoint must be unique.  If there is a chance where you may different files with the same file name, you need to use folders or separate libraries to avoid overwriting the files.  Typically this occurs when the document library is one component of a bigger solution and users typically see a filtered view of the library.


In Conclusion


There is a time and a place to use folders in SharePoint.  The misconception stems from the fact that it is different than how you would use folders in your standard file system.  You SHOULD be using SharePoint folders, just not for the same purpose you would outside of SharePoint.

Remember that if do use folders in SharePoint and the folder represents some information about the items inside of it, you should tag the items with the metadata.  You can look into setting up the "Column default values settings" the library / lists settings or using a SharePoint workflow to automate the task of populating the metadata for you.

I'm sure this list is not all inclusive so as I encounter more, I will update this post.  If you have any other cases where you should use folders, put it in the comments.

Friday, September 6, 2013

SharePoint Metadata: The Basics

If you are new to SharePoint or a casual user who wants to understand it better, I highly recommend that metadata be one of the first concepts you focus on learning.  SharePoint can be applied to a number of different uses (intranets, internets, extranets, collaboration, document management, etc...) but no matter how you use it, you will (or should) use metadata throughout the implementation.  Once you understand how metadata works in SharePoint, you will be able to review your content and start determining how to setup the metadata to best fit the needs of your organization.  In this post, I will show you the basics of metadata in SharePoint.  In future posts we will look at some of the more advanced concepts like site columns, content types and the content type hub.

Since everybody is use to working with documents, this post will compare a documents stored in a traditional file system (local machine, mapped drive, etc.).  It is important to know that in SharePoint, metadata can be added to other types of contents like announcements, calendar, discussions, tasks, etc....

What is is?

Metadata is data that provides information about other data or a way of identifying your information.  In the context of SharePoint, I would elaborate by adding that it is properties of the content that can be extracted out so users can easily navigate to it, search for it and automated processes can inspect these properties process and apply business rules.

Why is it important?

Metadata is essential in SharePoint for the following reason:
  • Navigating the information
    • Filter views by one or more pieces of metadata
    • Sort items by the metadata
  • Searching for information
    • Display the metadata in the search results
    • Search for all items based on the metadata
    • Refine your results based on the metadata
  • Process Automation
    • Workflows can inspect the metadata to determine what actions to perform based on the business rules
    • Route you content to the correct list/library or folder based on the metadata

Guess what?  You are already using it...

... in your folders

Traditional file systems are hierarchical in nature, typically each level represents a different piece of metadata for the document.

This image is a typical folder structure for a sales or consulting company.  The levels are defined as:

Level 1:  Represents the sales territory
Level 2:  Represents the companies found in that sales territory
Level 3:  Represents the types of documents
Level 4:  Represents the status of the document

Using this example, if a document was located in the Won folder, one could deduce the following metadata from it.

Sales Territory: North West
Company: MomCorp
Document Type: Proposals
Status: Won


... in your file names

It is typical of users to also embed metadata into the name of their files.  This is an example of file naming convention I commonly see when I am working with clients.  You can see that the document version and the date this version was effective is embedded into the file name.

How NOT to use it in SharePoint

At this point you may be thinking "If folders can specify metadata AND you can use folders in SharePoint, I can just keep doing things the way I'm currently doing them".

Sorry friend, it is not going to be that easy.

First of all, you won't be able to take advantage of any of the things I mentioned earlier that makes metadata so important in SharePoint.

Secondly, there are some fundamental issues with the folder approach.  Our earlier example works great if you are looking for files in this order.  First by sales territory, then company and then document type and then status  But what if you wanted a list of all proposals that are currently sent to the client.  You would have to open up the folder for every sales territory and every company.  Depending on the number companies you have, this process can take a long time and also be very error prone.  In addition, it is very easy to accidentally move a file to the wrong folder.  There is a time and a place for folders in SharePoint that we will explore in a future post.

Last, you really don't want to be storing the version number or date of the version in the document title.  SharePoint has automatic version numbering and version history built into it.  There are many benefits to using it and we will explore in a future post .

How to use it in SharePoint

In order to take advantage of what makes it so important in SharePoint you are going to have to take that data an put it into fields (or columns, based on your corporate vocabulary).  When the user uploads a document they will key in that metadata.  Below shows you how the same metadata we were capturing in the folders and file name looks like in SharePoint.


Now if I want to see all documents that status is 'Sent to Client', I just click on the column header and specify what values I want to see.


One last thing

The way I setup this metadata in my SharePoint example is the most basic way of doing it.  There are many other ways of setting up your metadata  using multiple libraries, site columns and content types and there is no "one way" it should be done.  It is all based on how you need to consume that content.

We will look at some more metadata concepts in future posts.

Wednesday, December 28, 2011

Spoofing the SPContext

Recently I had to use a set of libraries developed by a client to perform some complex data retrieval and calculations. The library looked up its settings from the property bag settings using SPContext.Current.Web.  I ran into an issue because I was trying to use the library from a Project Server Event Receiver that runs in the context of a Windows Service so the SPContext object was null.  For numerous good and not so good reasons, we could not modify the libraries to take an optional SPWeb object instead of relying on the SPContext.

After doing some research, I found out that this is a common problem for unit testing libraries that relied on the SPContext.

I created the SpoofedSPContext class to allow the developer to specify what the SPContext.Current.Web object should be set as.  This class implements IDisposable so it will clean up any SharePoint objects it creates.

It has constructors that mimics all the SPSite constructors and an additional one where you can pass in the SPWeb object.  In the case when you pass in the SPWeb object, you are responsible for disposing of it.  In all other cases, the SpoofSPContext object will handle cleaning up resources.

using System;
using System.IO;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace jds.SharePoint
{
 public class SpoofedSPContext : IDisposable
 {   
  SPSite _site = null;
  SPWeb _web = null;
  HttpContext _originalContext;
  bool _disposeObjects;  
   
  public SpoofedSPContext(Guid siteUID)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUID);
   _web = _site.RootWeb;
   Init();
  }

  public SpoofedSPContext(Guid siteUID, SPUrlZone urlZone)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUID, urlZone);
   _web = _site.RootWeb;
   Init();
  }

  public SpoofedSPContext(Guid siteUID, SPUserToken userToken)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUID, userToken);
   _web = _site.RootWeb;
   Init();
  }

  public SpoofedSPContext(Guid siteUID, SPUrlZone urlZone, SPUserToken userToken)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUID, urlZone, userToken);
   _web = _site.RootWeb;
   Init();
  }
  
  public SpoofedSPContext(string siteUrl)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUrl);
   _web = _site.OpenWeb();   
   Init();
  }

  public SpoofedSPContext(string siteUrl, SPUserToken userToken)
  {
   _disposeObjects = true;
   _site = new SPSite(siteUrl, userToken);
   _web = _site.OpenWeb();
   Init();
  }

  public SpoofedSPContext(SPWeb web)
  {
   _disposeObjects = false;
   _site = null;
   _web = web;
   Init();
  }


  void Init()
  {
   // Create a new request with the URL of the SharePoint that we want to spoof.
   HttpRequest request = new HttpRequest("", _web.Url, "");
   
   // Set the browser capabilities
   request.Browser = new HttpBrowserCapabilities();

   // Store the current HTTP context so we can revert back to it.
   _originalContext = HttpContext.Current;

   // Create a new HTTP context and set it as the current context.
   HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
   
   // Set the SPWeb context item.  This is what will make SPContext.Current.Web work
   HttpContext.Current.Items[@"HttpHandlerSPWeb"] = _web;

  }

  public void Dispose()
  {
   // Based on the constructor called, this instance may or may not 
   // be responsible for displosing of the SharePoint objects.
   if (_disposeObjects)
   {
    // If a SPWeb was created, dispose of it
    if (_web != null)
    {
     _web.Dispose();
     _web = null;
    }

    // If a SPSite was created, dispose of it 
    if (_site != null)
    {
     _site.Dispose();
     _site = null;
    }
   }

   // Set the current HTTP context back to what it was.
   HttpContext.Current = _originalContext;
  }
 }
}



Now in order to use it, all you have to do is create and instance of  the SpoofedSPContext class and call your objects while it's in scope like below.

using (SpoofedSPContext ctx = new SpoofedSPContext("http://sharepointsite.com"))
{
//Any code run here will see the SharePoint site specified as the value for SPContext.Current.Web
}