Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
ICustomRouter interface

ICustomRouter interface

Performs custom processing on documents before they are routed to the final location.

Namespace:  Microsoft.Office.RecordsManagement.RecordsRepository
Assembly:  Microsoft.Office.Policy (in Microsoft.Office.Policy.dll)

[SharePointPermissionAttribute(SecurityAction.LinkDemand, ObjectModel = true)]
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
public interface ICustomRouter

The custom router can also cancel default behavior and route the documents.

This topic includes two code examples.

The first code example is a custom router that inspects the content of a text file that is being saved and checks it for sensitive information.

The second example registers the custom router to the content organizer-enabled site.

using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using Microsoft.SharePoint;
using EcmDocumentRoutingWeb = Microsoft.Office.RecordsManagement.RecordsRepository.EcmDocumentRoutingWeb;
using EcmDocumentRouter = Microsoft.Office.RecordsManagement.RecordsRepository.EcmDocumentRouter;
using ICustomRouter = Microsoft.Office.RecordsManagement.RecordsRepository.ICustomRouter;
using CustomRouterResult = Microsoft.Office.RecordsManagement.RecordsRepository.CustomRouterResult;

namespace Microsoft.SDK.SharePointServer.Samples
    public class SampleDocumentRouter : ICustomRouter
        /// <summary>
        /// A sample custom router which inspects the content of a text file being saved for sensitive information
        /// If sensitive information is found, then the information is masked and saved by the custom router.
        /// </summary>
        /// <param name="contentOrganizerWeb">The Content Organizer that invoked the custom router.</param>
        /// <param name="recordSeries">Content type of the file being organized</param>
        /// <param name="userName">The name of the user who created the file. Value can be empty if the user no longer exists.</param>
        /// <param name="fileContent">Content of the file being saved.</param>
        /// <param name="properties">Metadata for the file being saved.</param>
        /// <param name="finalFolder">The final location that the content organizer determined for this file.</param>
        /// <param name="resultDetails">Any details that the custom router wants to furnish for logging purposes.</param>
        /// <returns>Whether the content organizer should continue to save the file in the designated location</returns>
        CustomRouterResult ICustomRouter.OnSubmitFile(
EcmDocumentRoutingWeb contentOrganizerWeb,
string recordSeries, // Content type name
string userName,
Stream fileContent,
Microsoft.SharePoint.RecordsRepositoryProperty[] properties,
SPFolder finalFolder,
ref string resultDetails)
if (contentOrganizerWeb == null)
    throw new ArgumentNullException("contentOrganizerWeb");
// We should have a Content Organizer enabled web 
if (!contentOrganizerWeb.IsRoutingEnabled)
    throw new ArgumentException("Invalid content organizer.");

//Change Domain\LoginName with the login name of a site user creating this file.
const string submitterLoginName = "Domain\\LoginName";
// Change MyFileName to the required file name. This will be used if this custom router needs to save the processed file to the final location.
string modifiedFileName = "MyFileName.txt";
// Read incoming content into a string so that we can look for ssn. 
// Do not close the stream that was passed in.
string fileContentString = string.Empty;
StreamReader sr = new StreamReader(fileContent);
    fileContentString = sr.ReadToEnd();
// regular expression to match social security numbers in file content.
Regex socialSecurityRegex = new Regex("([0-9]){3}-([0-9]){2}-([0-9]){4}");
MatchCollection matches = socialSecurityRegex.Matches(fileContentString);
if (matches.Count <= 0)
    // return a string which will be logged by the content organizer.
    resultDetails = "File was inspected and no sensitive data was found.";
    return CustomRouterResult.SuccessContinueProcessing;
    string submittingUserName = userName;
    if (string.IsNullOrEmpty(userName))
        // LoginName of the user creating the file
        submittingUserName = submitterLoginName;
    // We want to fix up the file content and save the file ourselves
    using (SPSite site = new SPSite(contentOrganizerWeb.DropOffZoneUrl))
        SPWeb web = site.OpenWeb();
        // User creating the file
        SPUser submittingUser = web.SiteUsers[submittingUserName];
        string fileName = modifiedFileName;
        // Create a Hashtable of properties which forms the metadata for the file
        Hashtable fileProperties = EcmDocumentRouter.GetHashtableForRecordsRepositoryProperties(properties, recordSeries);
        // Hide sensitive content in the file stream.
        fileContentString = socialSecurityRegex.Replace(fileContentString, "***-**-****");
        byte[] modifiedByteStream = Encoding.UTF8.GetBytes(fileContentString);
        // Modify content as required and then save the modified content ourselves.
        using (MemoryStream finalStm = new MemoryStream(modifiedByteStream))
finalStm.Write(modifiedByteStream, 0, modifiedByteStream.Length);
// Save the file here since we need to modify the file.
    true /*override versioning settings on the content organizer and create a new file*/, "");

        resultDetails = "File was inspected and sensitive data was found. File has been saved with a custom name.";
        return CustomRouterResult.SuccessCancelFurtherProcessing;

using System;
using Microsoft.SharePoint;
using Microsoft.Office.RecordsManagement;
using Microsoft.Office.RecordsManagement.RecordsRepository;

namespace Microsoft.SDK.SharePointServer.Samples
    /// <summary>
    /// Sample code to register an ICustomRouter implementation in a content organizer enabled web site.    
    /// </summary>
    public class CustomRouterRegistration
        static void Main(string[] args)
//Change http://SiteUrl to the absolute url of the content organizer enabled site where the custom router needs to be registered.
const string absoluteSiteUrl = "http://SiteUrl";
// Change Custom Router to the desired name to uniquely identify this custom router. 
// The name can be using to remove the registered router from the site and will be available in the edit rule page when configuring a rule.
const string customRouterName = "Custom Router";
// Assembly name of the ICustomRouter implementation
const string customRouterAssemblyName = "SampleDocumentRouter, Version=, Culture=neutral, PublicKeyToken=29af386697ceed40";
// Name of the class that implements the ICustomRouter interface.
const string customRouterClassName = "Microsoft.SDK.SharePointServer.Samples.SampleDocumentRouter";
using (SPSite contentOrganizerSiteCollection = new SPSite(absoluteSiteUrl))
    using (SPWeb contentOrganizerSite = contentOrganizerSiteCollection.OpenWeb())
        EcmDocumentRoutingWeb contentOrganizer = new EcmDocumentRoutingWeb(contentOrganizerSite);
        contentOrganizer.AddCustomRouter(customRouterName, customRouterAssemblyName, customRouterClassName);

© 2015 Microsoft