SharePoint 2013 Development Environment

Talbott Crowell's Software Development Blog

In this post, I’m going to describe my setup and some of the software and system requirements I needed for getting a SharePoint 2013 development environment up and running.  I’ll try to update this post as new releases of the Microsoft Office Developer Tools for Visual Studio 2012 are released or I make major changes or discoveries as time progresses.

sharepoint2013

Development Environment Setup

I’ve been using CloudShare for some of my SharePoint 2013 development ever since I purchased my new MacBook Air 11 inch which is maxed out at 8 GB and running Parallels so I can run Windows 7.  But recently I’ve decided to pull out my old Dell Precision M6500 laptop which has 16 GB to get a SharePoint 2013 development environment set up locally.  This beast is a great laptop for SharePoint development, but it is very heavy (the power supply is heavier then my MacBook Air). …

View original post 1,930 more words

Seven SharePoint Videos from //build/ 2012 Conference

How to delete broken EventReceiverDefinitions

When you use SharePoint 2010 event receivers for sites, webs or list you may get a broken event receiver definitions. It could be due to incorrect event receivers managment, you used packages that left broken event receiver definitions or something like that.

It is too hard to manually remove all broken definitions from whole site collection. I do not know useful tool for this purpose.

The following script do it for you. It is iterates through all webs and lists into site collection and remove all event receiver definitions that point to not exist assemblies.

open Microsoft.SharePoint

module EventReceiversCleaner =
    let private isAssemblyExist (assemblyName:string) =
        try
            match System.Reflection.Assembly.Load(assemblyName) with
             | null -> false
             | assembly -> assemblyName = assembly.FullName
        with
         | e -> false

    let private removeCandidates = ref List.Empty

    let CollectBroken (collection:SPEventReceiverDefinitionCollection) =
        for er in collection do
            if not (isAssemblyExist er.Assembly) then
                removeCandidates := er :: !removeCandidates

    let RemoveAll() =
        !removeCandidates |> List.iter
            (fun (er:SPEventReceiverDefinition) ->
                let name = sprintf "Assembly:'%s'" er.Assembly
                try
                    er.Delete()
                    printfn "Deleted : %s" name
                with
                 | e -> printf "Failed to delete: %s" e.Message)

try
    let url = "http://localhost/"
    printfn "Connecting to '%s'..."  url
    use site = new SPSite(url)
    site.EventReceivers |> EventReceiversCleaner.CollectBroken

    let rec collectFromLists (web:SPWeb) =
        printfn "Processing web '%s'..." web.ServerRelativeUrl
        web.EventReceivers |> EventReceiversCleaner.CollectBroken
        web.Webs |> Seq.iter collectFromLists

        for list in web.Lists do
            printfn "Processing list '%s'..." list.Title
            list.EventReceivers |> EventReceiversCleaner.CollectBroken

    use web = site.OpenWeb()
    collectFromLists web

    EventReceiversCleaner.RemoveAll()
    printfn "Finished."
with
    | e -> printfn "Exception : %s" e.Message

System.Console.ReadLine() |> ignore

P.S. You should compile it using .NET 3.5 and 64 bit project.

How to enumerate large document library

In this post by the size of the library i mean a total size of the documents in the library, not an item count.

It is relevant for cases when you need to enumerate over all documents in the library to process they, but the size of the library greater then an amount of the RAM on the SharePoint machine.

If you will do it using SPListItemCollection or ContentIterator and try to process all items as a single batch then you will get out of memory exception. It is happens because SharePoint OM download all binaries to the worker process (before or during enumeration).

This problem could be solved using content paging. You can split the library content into small pages and process it page by page. Before page processing we should release all resources allocated for previous page. Also, exist approach that rely on the  humanity of the content structure. We can assume that the size of the documents from one folder is not large and can be processed as a single batch. Such processing order also has advantages over simple paging.

Below you can find an C# example of processing:

using Microsoft.Office.Server.Utilities;
using Microsoft.SharePoint;

public static void EnumerateFolder(SPFolder root, Action<SPListItem> processAction, Action<SPListItem, Exception> exceptionAction)
{
  foreach (SPFolder folder in root.SubFolders)
  EnumerateFolder(folder, processAction, exceptionAction);

  var contentIterator = new ContentIterator();
  contentIterator.ProcessFilesInFolder(root, false,
      (file) => { processAction(file.Item);},
      (file, exception) =>
      {
         exceptionAction(file.Item, exception);
         return false;
      });
}

EnumerateFolder method enumerate over all files into provided SPFolder and all subfolders and execute processAction on each one. The last parameter into ProcessFilesInFolder is an error handler that will be executed after each exception from item processing. Line 13 mean that we do not stop document processing after each exception. More details about ProcessFilesInFolder method you can find here.

Below you can find the same F# example.


open Microsoft.SharePoint
open Microsoft.Office.Server.Utilities

let rec enumerate (root:SPFolder) processAction exceptionAction =
  for folder in root.SubFolders do
    enumerate folder processAction exceptionAction
  ContentIterator().ProcessFilesInFolder(root, false,
    (fun file -> processAction(file.Item)),
    (fun file ex -> exceptionAction(file.Item, ex); false));

P.S. To use ContentIterator you should add Microsoft.Office.Server to the project references.

How to change SPListItem Created or Modified date

Another often asked question is a ‘How to change SPListItem Created/Modified date’. Such task occur when you importing documents to the SharePoint  from another source when you want to save authorship and time information.

To update Created and Modified date you can use SPListItem indexer to modify infomation and call Update() to save changes.

To modify CreatedBy and ModifiedBy properties, you can use SPListItem indexer to modify fields with internal names Author and Editor. But you should convert SPUser object into string with following format “{userId};#{userName}”

Example you can find below:

public void ApplyMetadata(SPListItem item, DateTime created, DateTime modified, SPUser createdBy, SPUser modifiedBy)
{
  item["Created"] = created;
  item["Modified"] = modified;

  item["Author"] = GetStringByUser(createdBy);
  item["Editor"] = GetStringByUser(modifiedBy);

  item.Update();
}

private static string GetStringByUser(SPUser user)
{
  return user.ID + ";#" + user.Name;
}