In my previous post, https://realmpksharepoint.wordpress.com/2014/04/03/get-the-schemaxml-of-a-particular-webpart-of-a-sharepoint-page-using-web-services-c/ , I had explained, how we can use the WebService, WebPartPages.asmx. Here, I am going to use another method of this WebService, GetWebPartPage. This method, returns the content of the html page. The contents are as such that, they don’t include .js/.css files references. The returned string, contains, Page title, properties[MetaInfo], and all the WebParts [in a proper order] as they are present on the page.Now, all the WebParts, always have ZoneId of the page, in which they have been added. ZoneId, is a very important property, required to add a WebPart to a Zone. However, for some inexplicable reasons, neither the GetWebPart2 method of this service returns ZoneId nor does the SharePoint CSOM. They do for some WebParts, but for most they don’t return info regarding ZoneID.
It is for this reason, I was forced to call this method to get the info of all the WebParts at one go. Then, I had to parse this, returned string value, to identify the ZoneId of each of the WebParts based on their Guids. To get the Guids of each of the WebParts, you can use the SharePoint CSOM demonstrated here, https://realmpksharepoint.wordpress.com/2014/04/01/get-all-the-webparts-of-a-sharepoint-webpage-using-client-object-model-c/ .
Following is the implementation of the method, GetWebPartPage.
string webPageInfo = String.Empty; string webServiceUrl = ctx.Web.Url + "/_vti_bin/WebPartPages.asmx"; //say, we're trying to get the Home.aspx item of the List, SitePages. string documentName = String.Concat("SitePages/", listItem.FieldValuesAsText.FieldValues["FileLeafRef"]); StringBuilder sbEnvelope = new StringBuilder(); sbEnvelope.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sbEnvelope.Append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"); sbEnvelope.Append(String.Format( "<soap:Body>" + "<GetWebPartPage xmlns=\"http://microsoft.com/sharepoint/webpartpages\">" + "<documentName>{0}</documentName>" + "</GetWebPartPage>" + "</soap:Body>" , WebUtility.HtmlEncode(documentName))); sbEnvelope.Append("</soap:Envelope>"); HttpWebRequest req = (HttpWebRequest)WebRequest.Create(webServiceUrl); req.Method = "POST"; req.ContentType = "text/xml; charset=\"utf-8\""; req.Accept = "text/xml"; req.Headers.Add("SOAPAction", "\"http://microsoft.com/sharepoint/webpartpages/GetWebPartPage\""); req.UserAgent = "FrontPage"; req.UseDefaultCredentials = false; Uri targetSite = new Uri(ctx.Web.Url); SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)ctx.Credentials; string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite); req.CookieContainer = new CookieContainer(); req.CookieContainer.Add( new Cookie("FedAuth", authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()), String.Empty, targetSite.Authority)); using (Stream stream = req.GetRequestStream()) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(sbEnvelope.ToString()); } } WebResponse response = req.GetResponse(); Stream responseStream = response.GetResponseStream(); XmlDocument xDoc = new XmlDocument(); xDoc.Load(responseStream); if (xDoc.DocumentElement != null && xDoc.DocumentElement.InnerText.Length > 0) { webPageInfo = xDoc.DocumentElement.InnerText; //webPageInfo = webPageInfo.Substring(webPageInfo.IndexOf("")); //The above commented subString code was used further //to implement the logic of parsing. Since we're not //concerned with that hence it's not included here. }
Update-1
Recently I started getting, 403 Forbidden error while running this code. Certain modifications are required, to make this code work. They are defined in the following link,
403 Forbidden Error while calling GetWebPartPage SharePoint Online