Change WebPart Properties through the WSS Web Services API

I am currently working on WSS Site generation, and one important aspect of this is to set custom WebPart properties after a site is generated. In this case we are generating a WSS team site for MS CRM Opportunity objects. The WSS site is generated based on a template that contains a set of custom WebParts to display and work with Opportunity data from MS CRM.

In order for the WebParts to work properly we need to set the Opportunity ID in these webparts when the site is generated. After playing with the Web Services API for a day I found the proper approach.

I use the WebPartPagesWebService.GetWebPartProperties method and pass in the URL for the default.aspx in the generated site. This page contains the MS CRM WebParts. Note that the WebService endpoint for this query must be the recently created site. This can be confusing because the method accepts the entire url, and you can call it from the root site, or even the portal site.

Because our WebParts is part of the template used to generate the site, we don't know the GUID, and cannot use the WebPartPagesWebService.GetWebPart method to retreive the DWP xml (because it takes the guid as the only parameter). The GetWebPartProperties method, however, returns a WebParts element containing all the WebParts contained on the page:

<WebParts xmlns="http://microsoft.com/sharepoint/webpartpages">
 <WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/WebPart/v2" ID="3776e3f4-aa94-4a12-b464-018df99d7221">
   <Title>Announcements</Title>
   <FrameType>Default</FrameType>
   <Description />
   ...
 </WebPart>
 <WebPart>
   ...
 </WebPart>
</WebParts>

From here on it's really just a matter of manipulating the xml, but it can be a bit tricky.

We are going to use the WebPartPagesWebService.SaveWebPart method that requires the guid and the dwp xml. In other words we need to send in a single WebPart element to update the WebPart properties along with it's guid in a separate variable. In the xml we've got several webparts are returned; all with the guid as an attribute in the WebPart element.

To pick out one webpart we'll have to rely on the Title or another distinctive property. I've inferred XSD schema  for the webpart collection which greatly simplifies this task. The problem with creating strongly typed classes for the WebPart XML is that you'll have to include your custom properties aswell. It's probably just as easy to rely on XPath queries to locate the properties with your custom namespace and then extract the parent WebPart node.

When you've extracted the WebPart node and altered the properties (elements) you'll need to extract the guid as well to pass it to the SaveWebPart method. You dont have to remove the guid attribute from the XML.

 

No Comments