Document ID Provider, the last one?

By | 2010-06-21

For a client of ours we wanted to create a Custom SP2010 Document ID Provider. For this provider I wanted to be able to adjust and configure it so I can use it for other customers also.
First I needed to know how to create a Document ID Provider and found that: Tobias Zimmergren had an excelent article on creating you own SP2010 Document ID Provider.

Next in order to create a unique sequenced number I immediatly thought of SQL Server. And found that Ton Stegeman had an equally usefull post on how to create your own SPDatabase object in a SharePoint Farm.

Now I was set to create “the last Document ID Provider” for SP2010 I was ever going to write. Perhaps not but still, it should suffice for a LOT of clients of us!

I wanted to end up with an admin page like this:



This should then result in this document id:



So how to do this?
Step 1
Create a Database with a Table where I can store my generated document id’s

CREATE TABLE [dbo].[scoped_docid](
	[id] [bigint] IDENTITY(1,1) NOT NULL,
	[scopeid] [uniqueidentifier] NOT NULL,
	[objectid] [uniqueidentifier] NOT NULL,
	[scopedocid] [bigint] NULL,
	[scope] [varchar](100) NULL,
	[generateddocid] [varchar](150) NULL,
	[listid] [uniqueidentifier] NULL,
	[webid] [uniqueidentifier] NULL,
	[siteid] [uniqueidentifier] NULL,
	[webapplicationid] [uniqueidentifier] NULL,
	[farmid] [uniqueidentifier] NULL,
	[created] [datetime] NULL,
	CONSTRAINT [PK_scoped_docid] PRIMARY KEY CLUSTERED
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

And a stored procedure to Get/Insert ID’s:

-- =============================================
-- Author:		Stef van Hooijdonk
-- Create date: juni 2010
-- Description:
-- =============================================
CREATE PROCEDURE GetNextScopedDocID
	-- Add the parameters for the stored procedure here

	@scopeid uniqueidentifier  ,
	@scope varchar(100),
	@itemid uniqueidentifier
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;
	SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

	BEGIN TRANSACTION

	declare @result bigint
	declare @scopedindex bigint

	select @scopedindex=COALESCE([scopedocid],-1),@result=[id] from scoped_docid where [objectid] = lower(@itemid)

	if (@scopedindex is null)  begin
		-- coalesce for the first record will have MAX = null, and then we add 1
		select @scopedindex=COALESCE(MAX(scopedocid),0)+1 from scoped_docid where scope = lower(@scope)

		insert into [scoped_docid] (scopeid ,scope,objectid, scopedocid ) values( lower(@scopeid), lower(@scope),LOWER( @itemid), @scopedindex)
		select @result = SCOPE_IDENTITY()
	end
	COMMIT
	select @result as record,@scopedindex as docid
END
GO

There is more to it than this, but you can check out the downloads for all the details.
Step 2
Create an SPDatabase object for this Database, see the Ton Stegeman post!

Step 3
Create a Document ID Provider that uses this SPDatabase and generates Document ID’s based on some settings. What I did was generate the sequenced number in SQL and then format that in a method with the other variables. Generating a YEAR or DAY into a string is fairly easy.

Step 4
Create an Central Admin page to change the settings of our Document ID Provider ( see screenshot ).
You can use the SPFarm.Local.Properties to score your settings Farm Wide:

/// <summary>
/// The default farm wide scope setting for this DocumentProvider
/// </summary>
public ProviderScope Scope {
  get {
    ProviderScope result = ProviderScope.Farm;
    try {
      string setting = Settings.GetFarmSetting("CustomDocumentIDProvider.Scope");
      if (!string.IsNullOrEmpty(setting))
        result = (ProviderScope)Enum.Parse(typeof(ProviderScope), setting);
      }
    }
    catch (Exception exc) {
      LogException(exc);
    }
    return result;
  }
  set {
    Settings.SetFarmSetting("CustomDocumentIDProvider.Scope", value.ToString());
  }
}

The scope:

/// <summary>
/// Scopes for the Document ID Provider
/// </summary>
public enum ProviderScope {
	/// <summary>Farm wide scope</summary>
        Farm=1,
        /// <summary>Webapplication scope</summary>
        Webapplication = 2,
        /// <summary>SPSite/Site collection scope</summary>
        SiteCollection = 3,
        /// <summary>Site/Subweb (SPWeb) scope</summary>
        Site = 4,
        /// <summary>List scope</summary>
        List = 5,
        /// <summary>No scope</summary>
        None = 100
}

Downloads
Download solution
Download sources

How to use the solution

One thought on “Document ID Provider, the last one?

  1. Adam Dawson

    This is awesome. I installed this on my 2013 farm and everything worked great. My question now is can I set the document ID in each list item to a number that is being caried over from an old system? We are in the middle of migrating everything to SharePoint 2013 from some antiquated system and would like to keep the ID’s from this system seeing as everyone already knows what they are and reference them all over the place.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.