Pages

Tuesday 30 August 2011

Programmatically Submitting Files to the SharePoint Content Organizer

The content organizer in SharePoint 2010 is an interesting feature, particularly from an application development perspective as it gives you a fairly competent rules builder (why does it post back when you select a content type? Like seriously, Microsoft?) and routing engine, for free. We built something similar in FirstPoint for SharePoint 2007, but it was quite a bit of work. You can do all sorts of interesting things with this such as moving documents around based on metadata changes or externalizing the rules that determine where server generated documents should be routed to.

The content organizer can be accessed from the Official Files web service but it can also be accessed directly when building server applications such as event receivers or custom web services. One common scenario, for example, is using an event receiver for moving a document to a different folder or library if a user changes a metadata field. If I have a list of contacts organized into folders by last name (A-C, B-E, etc.), I'd want the system to automatically move a contact into the correct folder if a contact changes his or her last name. Without the content organizer and externalized rules, you'd either have to hard code the routing rules or design and code a system to externalize the routing rules, both sub-optimal solutions compared to the content organizer.

Behind the scenes, content organizer users a class called OfficialFileCore, you'll need to add a reference to Microsoft.Office.Policy.dll (found in the ISAPI directory) to your project. The following is some code that should give you an idea of how to call the OfficialFileCore.SubmitFile() method:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.Office.RecordsManagement.RecordsRepository;
using System.Collections;

// Namespace and class omitted for formatting purposes...

static void Main(string[] args)
{
Microsoft.SharePoint.OfficialFileResult result = Microsoft.SharePoint.OfficialFileResult.UnknownError;
string destination = null; // New location of the file is assigned to this string.

using (SPSite site = new SPSite("http://moss.dev.com/"))
using (SPWeb web = site.OpenWeb())
using (new SPMonitoredScope("Official File Receiver", uint.MaxValue, new ISPScopedPerformanceMonitor[] { new SPSqlQueryCounter(100) }))
{
SPFile file = web.GetFile("http://moss.dev.com/dropofflibrary/test1.docx");
byte[] bytes = file.OpenBinary();
string fileType = file.Item.ContentType.Name;
SPFieldCollection fields = file.Item.Fields;

List properties
= new List();

// Create a RecordsRepositoryProperty for each metadata field.
foreach (SPField field in fields)
{
try
{
string value = Convert.ToString(
field.GetFieldValue(Convert.ToString(file.Item[field.Title])));

Console.Out.WriteLine("Name:{0}, Type:{1}, Value:{2}",
field.Title, field.TypeAsString, value);

Microsoft.SharePoint.RecordsRepositoryProperty property =
new Microsoft.SharePoint.RecordsRepositoryProperty
{
Name = field.Title,
Type = field.TypeAsString,
Value = value
};

properties.Add(property);
}
catch (Exception exception)
{
// Some fields fail; not sure if they're consequential yet!
Console.Out.WriteLine(" - Failed to process field {0}", field.Title);
}
}

result = OfficialFileCore.SubmitFile(web, bytes, properties.ToArray(), fileType,
"http://moss.dev.com/dropofflibrary/test1.docx", "Charles", false, out destination);

// Seems that you have to manually delete the file.
file.Item.Delete();
}

Console.Out.WriteLine("1 > {0}", result);
Console.Out.WriteLine("2 > {0}", destination);
}

In this case, the source library is the drop off library. Note that if you programmatically add a file to the library, it doesn't actually get routed according to the content organizer rules; you'll still have to submit it manually in the UI or use the code outlined above to actually trigger the routing.

One final note: as far as I can tell, it seems that you have to manually delete the file from the source library once you successfully route the file.

1 comment:

  1. Thanks to http://charliedigital.com/2010/10/21/programmatically-submitting-files-to-the-sharepoint-content-organizer/

    ReplyDelete

Popular Posts