Wednesday, November 07, 2007

Minor migration problems pt2

this is a follow up from Minor migration problems, in that post I described how to quickly address this error using the toolbar-flip technique. Now this is ofcourse not really an option if you have a lot sitecollections and subsites. So I decided to create a console application that checks every site and modifies the toolbar...

So my first idea was to programmatically  create the toolbar-flip technique. Googling I found a topic that covered just this thing : Update ListViewWebPart to Remove or Hide Toolbar ToolbarType= None. Reading through that thread and trying the samples that were given there, I managed to flip the toolbar from Summary to None to Full. Unfortunately only the setting of the toolbar was flipped, not on the webpart itself, so the link was not recreated. Bugger.. but I was on the right track :)

It became obvious to use the reflection technique in combination with the SPView that is associated with a ListViewWebPart (see the thread about the details). I became curious how SharePoint rendered the Toolbar string for the "Summary toolbar" using the new (and thus proper) way and the old way.

Old Way:

<HTML><![CDATA[ <table width=100% cellpadding=0 cellspacing=0 border=0 > 
<tr> <td colspan='2' class='ms-partline'><IMG SRC='/_layouts/images/blank.gif' 
width=1 height=1 alt=''></td> </tr> <tr> <td class='ms-addnew' 
style='padding-bottom: 3px'> <img src='/_layouts/images/rect.gif' alt=''>&nbsp;
<a class='ms-addnew' ID='idAddNewDoc' href=']]>
</HTML><URL Cmd='New' /><HTML>?RootFolder=</HTML><GetVar Name='RootFolder'
 URLEncode='TRUE' /><HTML><![CDATA[' ONCLICK='javascript:NewItem(']]>
</HTML><URL Cmd='New' /><HTML>?RootFolder=</HTML><GetVar Name='RootFolder' 
URLEncode='TRUE' /><HTML><![CDATA[', true);javascript:return false;' target='_self'>]]
></HTML><HTML>Add new document</HTML><HTML><![CDATA[</a> </td> </tr> 
<tr><td><IMG SRC='/_layouts/images/blank.gif' width=1 height=5 alt=''></td></tr> </table>]]></HTML>

New Way:

<IfHasRights><RightsChoices><RightsGroup PermAddListItems="required"
 /></RightsChoices><Then><HTML><![CDATA[ 
<table width=100% cellpadding=0 cellspacing=0 border=0 > <tr> 
<td colspan="2" class="ms-partline"><IMG SRC="/_layouts/images/blank.gif" 
width=1 height=1 alt=""></td> </tr> <tr> <td class="ms-addnew" 
style="padding-bottom: 3px"> <img src="/_layouts/images/rect.gif" alt="">
&nbsp;<a class="ms-addnew" ID="idAddNewDoc" href="]]></HTML>
<HttpVDir /><HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML>
<ListProperty Select="Name" /><HTML><![CDATA[&RootFolder=]]>
</HTML><GetVar Name="RootFolder" URLEncode="TRUE" /><HTML>
<![CDATA[" ONCLICK="javascript:NewItem(']]></HTML><HttpVDir />
<HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML>
<ListProperty Select="Name" /><HTML><![CDATA[&RootFolder=]]>
</HTML><GetVar Name="RootFolder" URLEncode="TRUE" />
<HTML><![CDATA[', true);javascript:return false;" target="_self">]]>
</HTML><HTML>Add new document</HTML><HTML>
<![CDATA[</a> </td> </tr> <tr><td>
<IMG SRC="/_layouts/images/blank.gif" width=1 height=5 alt="">
</td></tr> </table>]]></HTML></Then></IfHasRights>

Seeing this, it was pretty clear to just modify the Toolbar string from the SPView. Check the code below on how I did this :

static void Main(string[] args)
{
   SPWebApplication wa = SPWebApplication.Lookup(new Uri(@"http://webapplication"));
   //Loop through all the sitecollections within the webapplication
   foreach (SPSite site in wa.Sites)
   {
       //Loop through all the subsites within the sitecollection
       foreach (SPWeb web in site.AllWebs)
       {
           try
           {
               //Open up the default.aspx page to retrieve all the webparts
               SPLimitedWebPartManager WPColl = web.GetLimitedWebPartManager("default.aspx", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
               //Loop through every webpart in the collection
               foreach (Microsoft.SharePoint.WebPartPages.WebPart wp in WPColl.WebParts)
               {
                   if (wp is Microsoft.SharePoint.WebPartPages.ListViewWebPart)
                   {
                       //Extend the properties of the webpart using the ListViewWebPart class
                       ListViewWebPart ListViewWp = (ListViewWebPart)wp;

                       //Only change the properties if this is a document library since all the other webparts like Tasks, Links use other links (they use newform.aspx instead of upload.aspx)
                       if (web.Lists[new Guid(ListViewWp.ListName.ToString())].BaseTemplate == SPListTemplateType.DocumentLibrary)
                       {
                           try
                           {
                               //Got this piece of code from https://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1946546&SiteID=1&pageid=0 by Bruce VB and Eugen Lechner
                               System.Reflection.PropertyInfo ViewProp = ListViewWp.GetType().GetProperty("View", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                               SPView spView = ViewProp.GetValue(ListViewWp, null) as SPView;

                               //The old and inproper links begin with the <HTML> bit first where as the proper link begins with <IfHasRights>
                               if (spView.Toolbar.StartsWith("<HTML>"))
                               {
                                   //I write out the url of the web and which document library for troubleshooting in case something does go wrong
                                   Console.WriteLine(web.Url.ToString());
                                   Console.WriteLine("Modifying: " + wp.Title.ToString());
                                   //The toolbar is being updated with the proper link
                                   spView.Toolbar = @"<IfHasRights><RightsChoices><RightsGroup PermAddListItems='required' /></RightsChoices><Then><HTML><![CDATA[ <table width=100% cellpadding=0 cellspacing=0 border=0 > <tr> <td colspan='2' class='ms-partline'><IMG SRC='/_layouts/images/blank.gif' width=1 height=1 alt=''></td> </tr> <tr> <td class='ms-addnew' style='padding-bottom: 3px'> <img src='/_layouts/images/rect.gif' alt=''>&nbsp;<a class='ms-addnew' ID='idAddNewDoc' href=']]></HTML><HttpVDir /><HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML><ListProperty Select='Name' /><HTML><![CDATA[&RootFolder=]]></HTML><GetVar Name='RootFolder' URLEncode='TRUE' /><HTML><![CDATA[' ONCLICK='javascript:NewItem(']]></HTML><HttpVDir /><HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML><ListProperty Select='Name' /><HTML><![CDATA[&RootFolder=]]></HTML><GetVar Name='RootFolder' URLEncode='TRUE' /><HTML><![CDATA[', true);javascript:return false;' target='_self'>]]></HTML><HTML>Add new document</HTML><HTML><![CDATA[</a> </td> </tr> <tr><td><IMG SRC='/_layouts/images/blank.gif' width=1 height=5 alt=''></td></tr> </table>]]></HTML></Then></IfHasRights>";
                                   spView.Update();
                               }

                           }
                           catch (Exception _error)
                           {
                               Console.WriteLine(_error.Message.ToString());
                           }
                       }

                   }
               }

               //If a meeting workspace is used, there is more than just 'default.aspx'. So we have to check the rest of the pages as well
               if (web.WebTemplate == "MPS")
               {
                   //The rest of the pages are kept in the "pages" folder
                   SPFolder srcFolder = web.Folders["pages"];
                   foreach (SPFile file in srcFolder.Files)
                   {
                       //Here we get the webparts from those specific pages
                       SPLimitedWebPartManager pagescollection = web.GetLimitedWebPartManager("pages/" + file.Name.ToString(), System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);
                       foreach (Microsoft.SharePoint.WebPartPages.WebPart _webpart in pagescollection.WebParts)
                       {
                           if (_webpart is Microsoft.SharePoint.WebPartPages.ListViewWebPart)
                           {
                               ListViewWebPart ListViewWp = (ListViewWebPart)_webpart;

                               if (web.Lists[new Guid(ListViewWp.ListName.ToString())].BaseTemplate == SPListTemplateType.DocumentLibrary)
                               {
                                   try
                                   {
                                       Guid webPartGuid = new Guid(((Microsoft.SharePoint.WebPartPages.ListViewWebPart)ListViewWp).ViewGuid);
                                       System.Reflection.PropertyInfo ViewProp = ListViewWp.GetType().GetProperty("View", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                                       SPView spView = ViewProp.GetValue(ListViewWp, null) as SPView;

                                       if (spView.Toolbar.StartsWith("<HTML>"))
                                       {
                                           Console.WriteLine(web.Url.ToString());
                                           Console.WriteLine(file.Name.ToString());
                                           Console.WriteLine("Modifying: " + _webpart.Title.ToString());

                                           
                                           spView.Toolbar = @"<IfHasRights><RightsChoices><RightsGroup PermAddListItems='required' /></RightsChoices><Then><HTML><![CDATA[ <table width=100% cellpadding=0 cellspacing=0 border=0 > <tr> <td colspan='2' class='ms-partline'><IMG SRC='/_layouts/images/blank.gif' width=1 height=1 alt=''></td> </tr> <tr> <td class='ms-addnew' style='padding-bottom: 3px'> <img src='/_layouts/images/rect.gif' alt=''>&nbsp;<a class='ms-addnew' ID='idAddNewDoc' href=']]></HTML><HttpVDir /><HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML><ListProperty Select='Name' /><HTML><![CDATA[&RootFolder=]]></HTML><GetVar Name='RootFolder' URLEncode='TRUE' /><HTML><![CDATA[' ONCLICK='javascript:NewItem(']]></HTML><HttpVDir /><HTML><![CDATA[/_layouts/Upload.aspx?List=]]></HTML><ListProperty Select='Name' /><HTML><![CDATA[&RootFolder=]]></HTML><GetVar Name='RootFolder' URLEncode='TRUE' /><HTML><![CDATA[', true);javascript:return false;' target='_self'>]]></HTML><HTML>Add new document</HTML><HTML><![CDATA[</a> </td> </tr> <tr><td><IMG SRC='/_layouts/images/blank.gif' width=1 height=5 alt=''></td></tr> </table>]]></HTML></Then></IfHasRights>";
                                           spView.Update();
                                       }

                                   }
                                   catch (Exception _error)
                                   {
                                       Console.WriteLine(_error.Message.ToString());
                                   }
                               }

                           }

                       }
                   }
               }
           }

           catch (Exception error)
           {
               Console.WriteLine(error.Message.ToString());
           }

           finally
           {
               web.Dispose();
               web.Close();
               site.Close();
               site.Dispose();
           }
       }
   }
}

So my thanks go out to Bruce VB and Eugen Lechner for guiding me in the right way ! :)

 

Technorati tags: , , ,

2 comments:

Hasan said...
This comment has been removed by the author.
digital certificate said...

Very helpful article ! I was always curious about all these complex algorithms that are being used in these ssl encryptions.