Muhammad Ali Khan

MS CRM 3.0, MS CRM 4.0, Sharepoint 2007 & Sharepoint 2010

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.

NewList1 

Before the update title code

 

NewList2b 

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. 

NewList3 

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’)

 NewList4

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

NewList5

 NewList6 

 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.

Advertisements

8 Responses to “Create, Rename SharePoint Document Library and Integerate With MS CRM 4.0”

  1. thank you allot, for the detailed post!!
    I look ahead to your next article !

  2. 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.
      https://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 :D.
        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 :(. Personally i don’t see any reason for not allowing it.
        you can post this question on sharepont forum on microsoft but they will suggest you the same thing.

  3. Timir Panchal said

    I forgot to mentioned here that i want to do it with remote machine.
    Thanks,

  4. 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 ???

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: