Microsoft SharePoint contains functionality for Records Management, which essentially is a storage for documents that you would like to store and manage in a separate records center to meet certain legal or other requirements or just to make backups of certain document revisions. To be able to create a Records Center you need to have Microsoft Office SharePoint Server 2007 (MOSS). On the other hand you only need Windows SharePoint Services 3.0 (WSS) to send documents to the Records Center.
You configure the Records Center connection in the Central Administration. When connecting to the Records Center all you do is specify a Url to a web service and a name. The Url points to a special MOSS web service called OfficialFile.asmx (http://server/_vti_bin/OfficialFile.asmx). Your receiving Records Center server does not have to be in the same farm as from where you send the document (and it should probably not be either). Another thing is that the receiving Records Center does not even have to be a SharePoint server. It’s just a web service and we can implement it anywhere we like.
I thought why not implement it using the Windows Azure technologies? This would be a great solution when you do not want to invest in either MOSS or a new MOSS farm, when you really want your important documents to be stored on a completely different physical location etc.
For this exercise I have used Visual Studio 2008, Windows Azure SDK and the Windows Azure Visual Studio plugin. You also need to have access tokens/claims to the Windows Azure beta.
To create our Cloud Records Center we need to create an Azure Web Role, which hosts the Records Management web service and a page to show our documents and some other logic. Our Records Center should also be able to handle some very basic record routing and metadata.
Note: the complete sample code can be downloaded here.
Create the Web Role project
First of all we need to fire up Visual Studio 2008 with the plugins as above and create a new Web Cloud Service called AzureRecordsCenter.
Create the data storage
Without digging to deep into the Windows Azure table and blob storage I just briefly describe how the storage is implemented. This sample has two tables; one for storing the routings and one to store information about the submitted documents. The blob storage is used to store the actual documents. The Windows Azure SDK contains a sample StorageClient which makes it really easy to work with the data, and this sample is used as a reference in the application.
I’ve created two classes to represent the tables; DocumentEntity and RecordRoutingEntity and a class that handles the actual data services called DataContext. The data classes has a primary key property combination; PartitionKey and RowKey (inherited from TableStorageEntity from the StorageClient sample) - I only use the PartitionKey and RowKey has a static value.
The RecordRoutingEntity is used to store the name and optional description of the record routings and the DocumentEntity contains some information about the documents and a reference (Guid) to the name of the blob.
Take a look at the code for more information.
To be able to add routings the default.aspx was modified and I also added a Setup.aspx page which creates the tables in the Windows Azure storage.
The OfficialFile.asmx web service
To be able to create our own Cloud Records Center we have to implement the same web service as MOSS offers - the OfficialFile.asmx. The .NET Framework SDK contains a great tool, wsdl.exe, for converting a WSDL from a web service into a server side interface. Use the Url to the web service from any of your MOSS servers.
1: wsdl /out:IRecordsRepositorySoap.cs /n:AzureRecordsCenter_WebRole /serverinterface http://xxxxx/_vti_bin/OfficialFile.asmx?WSDL
This will generate an IRecordsRepositorySoap.cs file containing the correct interface for the records management web service. So we create a new Web Service in our project, called OfficialFile.asmx, add our generated interface file to the solution and then we let this new web service implement the interface we extracted from the WSDL. The namespace for the web service is also changed into the same namespace as the official OfficialFile.asmx use.
1: [WebService(Namespace = "http://schemas.microsoft.com/sharepoint/soap/recordsrepository/")]
2: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
4: public class OfficialFile : System.Web.Services.WebService, IRecordsRepositorySoap
This interface now contains four methods:
- SubmitFile - the method which retrieves the submitted documents
- GetServerInfo - should return info about the implementation
- GetRecordRoutingCollection - returns all record routing types
- GetRecordRouting - returns info about a specified record routing
The three latter are pretty straight forward and the SubmitFile method receives the file, the route to use (the name of the Content Type) and all metadata of the file. First it creates the document entry in the Document table and the uploads the blob. My sample also validates that there is a valid route and otherwise returns an error.
Put it in the cloud
To get it all to work you have to create a new Hosted Service in the Windows Azure Developers Portal and then you have to create a Storage Account. Modify the Service Configuration of your cloud service to match your storage account.
Build the solution and use the Publish function from Visual Studio to publish your application to the cloud and put it in either the Staging or Production environment and wait for it to start (this may take a while).
Swapping between staging and production has been quite troublesome and results in an error or timeout quite often for me the last few days.
Browse to your cloud web application and add a route or two. The name of the route should correspond to the name of your Content Types.
In the image above I have added a new Route called Document.
To be able to send the documents from SharePoint to our cloud records center, all we have to do is go to Central Administration of your SharePoint farm and configure the Records Center Connection, found under Application Management/External Service Connections/Records Center. Enter the Url of your hosted service and append the OfficialFile.asmx path (http://nnnn.cloudapp.net/OfficialFile.asmx) and enter a name for your Records Center connection.
To try it out, just head on over to a Document Library and add a document and the open up the list item menu and choose Send To - Azure Records Center (in my case).
Wait for the file to be uploaded to your Cloud Records Center.
Then head back to your Azure web application and load the default page. You should now be able to see the document there and click on the link to bring it up.
If you upload a document of a content type that is not registered as a route, then you should get an error.
Now you know how to build a simple Records Center utilizing Windows Azure and known .NET techniques. This is in no way limited to Windows Azure, you can host it or similar solutions anywhere on any platform whenever you want.
If you want to have a Records Center and don’t want to buy a MOSS license, then this solution can be a good fit.
The provided code is in no way ready for production. It has no good exception handling nor security checks. It is provided as a sample for you to look at if you need to get started with either building a Records Center or just want to learn something about Windows Azure.
Have a nice summer!