Rebranding webpart URLs in runtime






4.60/5 (2 votes)
May 8, 2007
2 min read

23407
This article helps to change the old URLs to new URLs referred to in the SharePoint webparts which is useful during the migration process
Introduction
This article gives one of the practical usages of the .NET reflection concept in SharePoint webparts. We can make use of this concept to change the properties of the SharePoint webparts during runtime in a bulk manner. I have used this for changing the URLs from old to new referred in the CorasWorks webparts and Image webparts.
Background
The CorasWorks suite is used for roll up of all the lists in a SharePoint system. The challenge here is when the portal and the sites are restored, the weparts in the new system will have the links pointed to old URL. The CorasWorks store the "SiteURL
" and "ListNames
" properties in the .dwp file of that webpart.
All SharePoint developers know that the webparts are associated with a .dwp file and the data associated with the webparts are not stored in the database. The webpart specific data are stored in the .dwp file and so this has to be changed to the new one. You might wonder what the big deal is, but suppose the system has thousands of wss sites and least one CorasWorks webpart is there. Hope you can recognize the criticality now.
I need to really appreciate the "Reflection" concept of .NET here.
- The webparts are iterated for all the webs using the
GetWebPartCollection
of theSPWeb
object and the webpart type is identified usingGetType()
method. - Using the
GetMember()
method of the object, theMembers[]
array is created. - A
PropertyInfo
object is created based on theMembers
element. - Then the
GetValue()
andSetValue()
method ofPropertyInfo
helps in getting the old value, replacing the new one and setting it back.
Once the value is set, the webpart values are saved using the SaveChanges
method of the SPWebPartCollection
object.
Note: This can be done only for the wss sites and not for portal areas due to permission restriction of saving the webpart values.
Using the code
The code shows looping through the virtual servers (the IIS websites linked to SharePoint) and all further sites. It looks for the type of the webpart.
SPGlobalAdmin global = new SPGlobalAdmin();
string webname = string.Empty;
#region looping Virtual servers
for(int count=1; count<=2; count++)
{
SPSiteCollection allSitesOnServer = global.VirtualServers[count].Sites;
int totalSites = allSitesOnServer.Count;
for(int sitesCount =0;sitesCount<totalSites;sitesCount++)
{
try
{
SPSite allSites = allSitesOnServer[sitesCount];
SPWebCollection allWebs = allSites.AllWebs;
#region looping web collection
foreach(SPWeb currentWeb in allWebs)
{
webname = currentWeb.Url ;
// Get the webpart collection
SPWebPartCollection webParts = currentWeb.GetWebPartCollection
("default.aspx",Storage.Shared);
for(int i=0; i<webParts.Count;i++)
{
WebPart currentWebPart = webParts[i];
object obj = null;
Type typeobj = currentWebPart.GetType();
// condition to check the webpart is of type ImageWebpart.
// you can put which webpart you are looking for.
if(currentWebPart.GetType().FullName.EndsWith
("ImageWebPart"))
{
Log("The Image webparts " +
currentWebPart.GetType().FullName);
Log("Info of " + currentWeb.Url + ":");
currentWebPart.AllowZoneChange = true;
// Read the properties and change to the
// new values in the webpart
WebPart newWebPart = ReadUpdatePropertyValues
(currentWebPart,typeobj,obj,oldUrl,newUrl);
// Save the changes to the webpart
webParts.SaveChanges(newWebPart.StorageKey);
}
}
}
#endregion
}
catch(Exception ex)
{
Log("Error in : " + webname + "--->" + ex.Message);
}
}
}
public static WebPart ReadUpdatePropertyValues
(WebPart wpart,Type wptype, object obj,string oldUrl,string newUrl)
{
try
{
// string array to get selected properties
string[] wpProps = new string[]{"ImageLink"};
#region looping through properties
foreach (string wpProp in wpProps)
{
MemberInfo[] members = wptype.GetMember(wpProp);
if(members.Length != 1)
{
Log(failed+": Not handled - No required property " +
wpart.Title );
// counter to find the number of unhandled coras webparts
failed++;
}
else
{
switch(members[0].MemberType)
{
case MemberTypes.Property :
{
PropertyInfo prop = (PropertyInfo)members[0];
// Gets the value of the property
obj = prop.GetValue(wpart, new object[0]);
string newurl = obj.ToString().Replace(oldUrl,newUrl);
// Log("OLD URL : " + oldUrl );
if(newurl != obj.ToString())
{
object strVal = (object)newurl;
// Sets the value of the property
prop.SetValue(wpart, strVal ,new object[0]);
Log(changed + ": " + wpart.Title +
" : Changed property");
Log(changed + ": " + newurl +
" : Changed property");
changed++;
}
}
break;
case MemberTypes.Field :
{
FieldInfo field = (FieldInfo)members[0];
obj = field.GetValue(wpart);
string newurl = obj.ToString().Replace(oldUrl,newUrl);
object strVal = (object)newurl;
field.SetValue(wpart,strVal);
}
break;
default :
throw new Exception("Not found");
}
}
Log(success +": " +wpart.Title+" : Has property");
// counter to find the number of coras webparts
// which has that property
success++;
}
#endregion
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
return wpart;
}