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)
Syntax
'Declaration
<SharePointPermissionAttribute(SecurityAction.LinkDemand, ObjectModel := True)> _
<SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel := True)> _
Public Interface ICustomRouter
'Usage
Dim instance As ICustomRouter
[SharePointPermissionAttribute(SecurityAction.LinkDemand, ObjectModel = true)]
[SharePointPermissionAttribute(SecurityAction.InheritanceDemand, ObjectModel = true)]
public interface ICustomRouter
Remarks
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.
Examples
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;
}
else
{
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.
EcmDocumentRouter.SaveFileToFinalLocation(contentOrganizerWeb,
finalFolder,
finalStm,
fileName,
"",
fileProperties,
submittingUser,
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=1.0.0.0, 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);
}
}
}
}
}
See Also
Reference
Microsoft.Office.RecordsManagement.RecordsRepository Namespace