Create, Rename SharePoint Document Library and Integerate With MS CRM 4.0
Posted by Ali Khan on July 31, 2009
In this post, I will show you how to create and then rename document library in Sharepoint. While creating a document library is a very common task, but there are times when you want to rename the document library as well. Suppose you want integration between MS CRM 4.0 Account Entity and the SharePoint Document Library, so whenever the account entity is created you create a document library on the name of an account and when the account is re-named, you rename the document library again. Off course, it’s understood that you will create & rename document library from account entity Plugin.
Creating a document library is a straight forward task, you can either use the SPWeb.Lists.Add() Method or the List.asmx webservice to create a new document library.
Here is how you can create a document library from the lists.asmx webservice
Create a New Document Library
You can put the following code in the create event of the account entity plugin.
Lists objList = new Lists();
objList.Url = “http://moss:32901/sites/testsite/_vti_bin/Lists.asmx”;
objList.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
XmlNode objNode = objList.AddList(“My New List”, “Using Default credit”, 101);
Console.WriteLine(objNode.OuterXml);
Well, there is no API available for re-name document library neither in the lists.asmx or any other webserivce and nor in the Micorosoft.Sharepoint.dll assembly.
The following code will only change the title of the Document Library and it will not rename the document library itself.
Lists listService = new Lists();
listService.Url = “http://moss:32901/sites/testsite/_vti_bin/Lists.asmx”;
listService.Credentials = new System.Net.NetworkCredential(“administrator”, “pass@word1″, “litwareinc”);
XmlNode ndList = listService.GetList(“My New List”);
XmlNode ndVersion = ndList.Attributes["Version"];
XmlDocument doc = new XmlDocument();
doc.LoadXml(ndList.OuterXml);
string listID = ndList.Attributes["ID"].Value;
XmlDocument xmlDoc = new System.Xml.XmlDocument();
XmlNode ndProperties = xmlDoc.CreateNode(XmlNodeType.Element, “List”,“”);
XmlAttribute ndTitleAttrib = (XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute,“Title”, “”);
XmlAttribute ndDescriptionAttrib =
(XmlAttribute)xmlDoc.CreateNode(XmlNodeType.Attribute,“Description”, “”);
ndTitleAttrib.Value = “My New List Updated”;
ndDescriptionAttrib.Value = “New Description Here”;
ndProperties.Attributes.Append(ndTitleAttrib);
ndProperties.Attributes.Append(ndDescriptionAttrib);
try
{
XmlNode ndReturn = listService.UpdateList(listID,
ndProperties, null, null, null, ndVersion.Value);
MessageBox.Show(ndReturn.OuterXml);
}
catch (Exception ex)
{
MessageBox.Show(“Message:\n” + ex.Message + “\nStackTrace:\n” +
ex.StackTrace);
}
As Obvious from the above code, the title of the document library will be updated but not the URL. So if the URL of the list was http://moss:32901/sites/testsite/My New List/ before the above code was executed it will remain the same after the above code is executed (http://moss:32901/sites/testsite/My New List/), as shown in the figure below.
Before the update title code
After the Update Title code
As you can see only the title is updated and not the actual List name, the URL of the list remains un-changed as see in the address bar.
Rename Document Library:-
First question you may ask, why would we need to rename a document library, well it’s a very common requirement if you are integerating SharePoint with other products like MS CRM. Now suppose you create an account “Adventure Wroks” (Note the dilberate spelling mistake) and the document library gets created. Now the URL will be something like this http://moss:32901/sites/testsite/Adventure Wroks/ . Later you realized that there is a spelling mistake and you want to rename the account entity to (Adventure Works), but at the same point you want the url to be updated as well to something like this http://moss:32901/sites/testsite/Adventure Works/ without effecting all the documents and the folder that you already have in your document library.
So what should be our solution, one approach is to use account id (guid) as the document library name which off-course will not changed but it will not look anything meanfull, e.g. http://moss:32901/sites/testsites/9C39AE6D-E96C-488D-8BA3-2624F2AAE4BE/ . But it doesn’t make any sense to the end users.
Well, now I will show you how to rename the document library from the .net code. But First
Warning: – Please note the rename document library code (below) is not a supported customization of sharepoint. Although I have tested the below code in development senarios to be working with 100% success, but I will not be liable for any data lost or damages to sharepoint that may be caused by the rename document library code (below).
If you have the list Id and run a simple query to the “alldocs” table, you may found out something like below which could be the reason of not providing the rename functionality to the document library.
Run this query against the “WSS_Content” database.
(select * from alldocs where listid=’4D62A2C4-DDEA-438E-86D2-64DCB67166E8′)

As you can see the complete URL’s to all the folders and the documents that are created inside the list is maintained.
As clearly seen from the above diagram, there is an UPDATE Analomy and it violates the 2nd Normal Form of normalization. Off-course there could be reason to maitain the data in above format, like performance, easing indexing for crawlers or may be lesser joins to the table, but that is another topic. Just to surprise you more, “alldocs” is not the only table that is containing the list nameJ. Unfornatley it is not the best of the database desgin.
Any way, so here is the code to update the document library name, I have used the SqlTransaction object just to make sure we commit if all the updates are successful or rollback completely in case of any errors.
You can put the below code in the update event of the account entity plugin.
private void RenameDocumentLibrary()
{
string oldListName = “My New List”;
string newListName = “My New List Updated”;
// first thing first, check if the new list name is valid
if (!ValidListName(newListName))
throw new InvalidOperationException(“List name is not valid”);
Lists listService = new Lists();
listService.Url = “http://moss:32901/sites/testsite/_vti_bin/Lists.asmx”;
listService.Credentials = new System.Net.NetworkCredential(“administrator”, “pass@word1″, “litwareinc”);
XmlNode ndList = listService.GetList(oldListName);
XmlDocument doc = new XmlDocument();
doc.LoadXml(ndList.OuterXml);
string listID = ndList.Attributes["ID"].Value;
SqlConnection objCon = null;
SqlTransaction objTrans = null;
try
{
string connectionStr = “Data Source=moss;Initial Catalog=WSS_Content;user id=alitest;password=alitest;”;
objCon = new SqlConnection(connectionStr);
objCon.Open();
objTrans = objCon.BeginTransaction();
// step 0: first reterview the site in which list is contained.
// These ids will be used later in the update process
string sql = “select top 1 siteid from alldocs where listid=’” + listID + “‘”;
SqlCommand cmd = new SqlCommand(sql, objCon, objTrans);
string siteID = cmd.ExecuteScalar().ToString();
// step 1: first update the title of the list
sql = “update alllists set tp_title = @p1 where tp_ID=@p2″;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.Parameters.AddWithValue(“@p1″, newListName);
cmd.Parameters.AddWithValue(“@p2″, listID);
cmd.ExecuteNonQuery();
// step 2: now update the leaf name of the list
sql = “update alldocs set leafname = ‘” + newListName + “‘” +
” where listid = ‘” + listID + “‘ and leafname=’” + oldListName + “‘”;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.ExecuteNonQuery();
// step 3: now update all the files, folders for the list
sql = “update alldocs set dirname = replace(dirname,’” + oldListName + “‘,’” + newListName + “‘)” + ” where listid = ‘” + listID + “‘”;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.ExecuteNonQuery();
// step 4: now update all links to the documents in “alluserdata” // in the table
sql = “update alluserdata set tp_dirname=replace(tp_dirname,’” + oldListName + “‘,’” + newListName + “‘) “ + ” where tp_listid = ‘” + listID + “‘”;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.ExecuteNonQuery();
// step 5: now update the build dependencies
sql = “update builddependencies set dirname = replace(dirname,’” + oldListName + “‘,’” + newListName + “‘) “ + ” where dirname like ‘%/” + oldListName + “/%’ and siteid=’” + siteID + “‘”;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.ExecuteNonQuery();
// step 6: finally, now update the eventcache table
sql = “update eventcache set itemfullurl = replace(itemfullurl,’” + oldListName + “‘,’” + newListName + “‘) “ + ” where itemfullurl like ‘%/” + oldListName + “/%’ and siteid=’” + siteID + “‘”;
cmd = new SqlCommand(sql, objCon, objTrans);
cmd.ExecuteNonQuery();
// if everything goes fine, commit transaction
objTrans.Commit();
MessageBox.Show(“Document Library re-named”);
}
catch (Exception ex)
{
// roll back gracefully, in case of any errors
if (objTrans != null)
objTrans.Rollback();
throw;
}
finally
{
if (objTrans != null)
objTrans.Dispose();
if (objCon != null)
objCon.Close();
objTrans = null;
objCon = null;
}
}
bool ValidListName(string newListName)
{
// You can used regular expression for this purpose
if (newListName.Contains(“~”) || newListName.Contains(“`”) || newListName.Contains(“!”) || newListName.Contains(“@”)
|| newListName.Contains(“#”) || newListName.Contains(“%”) || newListName.Contains(“^”) || newListName.Contains(“*”)
|| newListName.Contains(“(“) || newListName.Contains(“)”) || newListName.Contains(“\”") || newListName.Contains(“\’”)
|| newListName.Contains(“:”) || newListName.Contains(“;”))
return false;
return true;
}
As you can see in the pictures below, the above code will not only update the URL to the document library but it will update the URL’s of all the documents and the folders that are contained inside that document library, so if the URL to a document was http://moss:32901/sites/testsite/My New List/ Ali test document.docx (before rename), then after the above code is executed, it will be like this http://moss:32901/sites/testsite/My New List Updated/Ali test document.docx

Note: If you are using the moss search service; you may have to run the crawler again on this document library since the document library is renamed.
Know Orange said
thank you allot, for the detailed post!!
I look ahead to your next article !
Timir Panchal said
This artical is very useful and thanks for it.
I have a document folder thats in the other folder eg (site/FolderLevel1/FolderLevel2). I want to rename the folder at Level 2. Do you have any Idea how to do it?
I do not have access to sharepoint database. Is there any other way to do it.
I really appriciate your help.
Ali Khan said
Hi,
check this article. i created a custom webservice, and deployed it to the sharepoint. since it is a webservice you can call it from any-where if you specify the appropriate credentials.
http://malikhan.wordpress.com/2009/08/07/creating-custom-webservice-in-sharepoint-2007/
This webservice has two method IsFolderExits() and RenameFolder().
I hope it resolves your issue.
Timir Panchal said
Thanks for your reply Ali.
What I found is the server team is not allwing
#1. To deploy any custom webservice on the sharepoint server.
#2. To give an access to SharePoint Database.
Is ther any other way to do it. Really appriciate your help.
Ali Khan said
Well, they are restricting you in many ways
.
. Personally i don’t see any reason for not allowing it.
I am not sure, why they are not allowing you to create custom webservice. because Client API is not available in Sharepoint 2007.
It would have been possible in Sharepoint 2010 with Client API because Client API dll can be added to your VS project (on client machine). and it will provide all the featurs of Microsoft.Sharepoint.dll.
But coming back to Sharepoint 2007, i am not sure, but with out custom webservice it won’t be possible
you can post this question on sharepont forum on microsoft but they will suggest you the same thing.
Timir Panchal said
I forgot to mentioned here that i want to do it with remote machine.
Thanks,
Renu said
I am trying to create new three folder automatically inside new document library, whenever i create a new document library inside three folder automatically.
how can we acheive this senario ???
Ali Khan said
I think you have to capture a list event. check these links.
http://msdn.microsoft.com/en-us/library/ff398052.aspx
http://www.sharepointdev.net/sharepoint–development-programming/event-when-list-instance-is-created-58353.shtml