403 Forbidden Error while calling GetWebPartPage SharePoint Online

Premise

I had this code, https://realmpksharepoint.wordpress.com/2014/04/07/get-webpart-page-of-a-sharepoint-site-using-web-services-c/ which I was using to download the html content of a SharePoint page along with all the web parts. The importance of this method is that it eliminates the external file references, so in the response, you will get the schema of all the web parts of that page only.

Issue

The code was working fine until recently, when it suddenly stopped working and I started to receive the error, 403 Forbidden.

Continue reading

Add a new WebPart to a SharePoint Site using Client Object Model C#

We can also add a new WebPart to a SharePoint page using CSOM. Before I proceed further, let me first point out the three imp parameters that are needed to perform this action. They are:-

  • ZoneID
  • ZoneIndex
  • WebPartXml

I am going to confine this blog to the items of the two Lists only, Pages(created by default for publishing site) and SitePages(created by default for TeamSite). Both these List, have web page as listItems. However, there’s a contrasting different,
SitePages have only 1 container[Zone] for everything, RichContent (ZoneID=wpz)
whereas,
Pages have various containers[Zones], Header, Footer, Left, Right, RichContent (ZoneID=wpz), etc.

There’s one thing to note here that, the value of ZoneID, for RichContent, is always wpz.

Below is the code snippet for adding a WebPart to a SitePage/Pages

ClientContext ctx = new ClientContext(weburl);
ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

SP.List list = ctx.Web.Lists.GetByTitle("Site Pages");
ctx.Load(list);
CamlQuery cQuery = new CamlQuery();
ListItemCollection ltItemCollection = list.GetItems(cQuery);

ctx.Load(ltItemCollection);
ctx.ExecuteQuery();

ListItem ltItemHome = ltItemCollection.FirstOrDefault(p => p.DisplayName == "Home");
SP.File file = ltItemHome.File;

ctx.Load(ltItemHome);
ctx.Load(file);
ctx.ExecuteQuery();

LimitedWebPartManager limitedWebPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
WebPartDefinitionCollection webPartDefCollection = limitedWebPartManager.WebParts;

WebPartDefinition webPartDef = limitedWebPartManager.ImportWebPart(webPartXml);
WebPartDefinition newWebPartDef = limitedWebPartManager.AddWebPart(webPartDef.WebPart, stringZoneId, intZoneIndex);

//ctx is the ClientContext
//Get the Guid of the newly added WebPart 
ctx.Load(newWebPartDef, w => w.Id);
ctx.ExecuteQuery();

So, if your stringZoneId is anything but ‘wpz’, your newly created WebPart will appear on the page at its appropriate zone. Now, if you’re attempting to add this WebPart to the zone, ‘wpz‘[RichContent] then, there’s one more step to go. For, RichContent, you have to specify the exact position of its appearance after adding it to the page. Since, a RichContent can contain text as well as WebParts, you have the liberty to position it accordingly inside the RichContent. For this ex, I will add it at the end of the RichContent, so that, if the RichContent contains some values(text, image, or WebParts) then, my newly added WebPart, will appear after them.

if (stringZoneId == "wpz")
{
    if (ltItemHome.FieldValuesAsHtml.FieldValues.ContainsKey("WikiField"))
    {
        //SitePage item
        ltItemHome["WikiField"] = String.Concat(ltItemHome["WikiField"], "
", GetEmbeddedWPString(newWebPartDef.Id), "
");
    }
    else if (ltItemHome.FieldValuesAsHtml.FieldValues.ContainsKey("PublishingPageContent"))
    {
        //Pages item
        ltItemHome["PublishingPageContent"] = String.Concat(ltItemHome["PublishingPageContent"], "
", GetEmbeddedWPString(newWebPartDef.Id), "
");
    }
    ltItemHome.Update();
    ctx.ExecuteQuery();
}

Here, I am appending, a constant string (GetEmbeddedWPString(Guid wpGuid)) with the new WebPartId to the field, WikiField, for SitePages and, PublishingPageContent, for the List Pages. The constant string format is

private string GetEmbeddedWPString(Guid wpGuid)
{
    // set the web part's ID as part of the ID-s of the div elements
    string wpForm = @"
<div class=""ms-rtestate-read ms-rte-wpbox"">

<div class=""ms-rtestate-notify ms-rtegenerate-notify ms-rtestate-read {0}"" id=""div_{0}"">
                            </div>


<div id=""vid_{0}"" style=""display:none"">
                            </div>

                       </div>

";
    
    return string.Format(wpForm, wpGuid);
}

Just for reference, I have posted the schemaXml of a Rss WebPart here, https://realmpksharepoint.wordpress.com/2014/04/10/sample-rss-webpart-schemaxml/

Sample Rss WebPart SchemaXml

Following is the schemaXml of a Rss WebPart. SchemaXml is essential to add a WebPart to a SharePoint WebPage. It contains the settings of a given WebPart. Following I have highlighted the FeedUrl property of this WebPart. This blog has been posted in conjunction with the blog, https://realmpksharepoint.wordpress.com/2014/04/10/add-a-new-webpart-to-a-sharepoint-site-using-client-object-model-c/
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.Portal.WebControls.RSSAggregatorWebPart, Microsoft.SharePoint.Portal, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>Cannot import this web part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="InitialAsyncDataFetch" type="bool">False</property>
        <property name="ChromeType" type="chrometype">Default</property>
        <property name="ListName" type="string">{B60CCD97-C15A-462E-82E7-9684FA71D9A9}</property>
        <property name="Height" type="string" />
        <property name="CacheXslStorage" type="bool">True</property>
        <property name="Default" type="string" />
        <property name="ParameterBindings" type="string">&lt;ParameterBinding Name="RequestUrl" Location="WPProperty[FeedUrl]"/&gt;</property>
        <property name="AllowZoneChange" type="bool">True</property>
        <property name="AutoRefresh" type="bool">False</property>
        <property name="XmlDefinitionLink" type="string" />
        <property name="DataFields" type="string" />
        <property name="FeedLimit" type="int">5</property>
        <property name="Hidden" type="bool">False</property>
        <property name="NoDefaultStyle" type="string" null="true" />
        <property name="XslLink" type="string" null="true" />
        <property name="ViewFlag" type="string">0</property>
        <property name="CatalogIconImageUrl" type="string" />
        <property name="FireInitialRow" type="bool">True</property>
        <property name="AutoRefreshInterval" type="int">60</property>
        <property name="AllowConnect" type="bool">True</property>
        <property name="FeedUrl" type="string">http://wxdata.weather.com/wxdata/weather/rss/local/INXX0300?cm_ven=LWO&amp;cm_cat=rss</property>
        <property name="AllowClose" type="bool">True</property>
        <property name="ShowWithSampleData" type="bool">False</property>
        <property name="Xsl" type="string">&lt;xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
               version="1.0" exclude-result-prefixes="xsl ddwrt msxsl rssaggwrt" 
               xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
               xmlns:rssaggwrt="http://schemas.microsoft.com/WebParts/v3/rssagg/runtime"
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
               xmlns:rssFeed="urn:schemas-microsoft-com:sharepoint:RSSAggregatorWebPart"
               xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"
               xmlns:rss1="http://purl.org/rss/1.0/" xmlns:atom="http://www.w3.org/2005/Atom"
               xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
               xmlns:atom2="http://purl.org/atom/ns#"&gt;

    &lt;xsl:param name="rss_FeedLimit"&gt;5&lt;/xsl:param&gt;
    &lt;xsl:param name="rss_ExpandFeed"&gt;false&lt;/xsl:param&gt;
    &lt;xsl:param name="rss_LCID"&gt;1033&lt;/xsl:param&gt;
    &lt;xsl:param name="rss_WebPartID"&gt;RSS_Viewer_WebPart&lt;/xsl:param&gt;
    &lt;xsl:param name="rss_alignValue"&gt;left&lt;/xsl:param&gt;
    &lt;xsl:param name="rss_IsDesignMode"&gt;True&lt;/xsl:param&gt;

        &lt;xsl:template match="rss"&gt;
            &lt;xsl:call-template name="RSSMainTemplate"/&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template match="rdf:RDF"&gt;
            &lt;xsl:call-template name="RDFMainTemplate"/&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template match="atom:feed"&gt;
            &lt;xsl:call-template name="ATOMMainTemplate"/&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template match="atom2:feed"&gt;
            &lt;xsl:call-template name="ATOM2MainTemplate"/&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="RSSMainTemplate" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:variable name="Rows" select="channel/item"/&gt;
            &lt;xsl:variable name="RowCount" select="count($Rows)"/&gt;
            &lt;div class="slm-layout-main" &gt;            
            &lt;div class="groupheader item medium"&gt;
                        &lt;a href="{ddwrt:EnsureAllowedProtocol(string(channel/link))}"&gt;
                            &lt;xsl:value-of select="channel/title"/&gt;
                        &lt;/a&gt;
            &lt;/div&gt;            
            &lt;xsl:call-template name="RSSMainTemplate.body"&gt;
                &lt;xsl:with-param name="Rows" select="$Rows"/&gt;
                &lt;xsl:with-param name="RowCount" select="count($Rows)"/&gt;
            &lt;/xsl:call-template&gt;
            &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="RSSMainTemplate.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="Rows"/&gt;
            &lt;xsl:param name="RowCount"/&gt;
            &lt;xsl:for-each select="$Rows"&gt;
                &lt;xsl:variable name="CurPosition" select="position()" /&gt;
                &lt;xsl:variable name="RssFeedLink" select="$rss_WebPartID" /&gt;
                &lt;xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" /&gt;
                &lt;xsl:if test="($CurPosition &amp;lt;= $rss_FeedLimit)"&gt;
                    &lt;div class="item link-item" &gt;
                            &lt;a href="{concat(&amp;quot;javascript:ToggleItemDescription('&amp;quot;,$CurrentElement,&amp;quot;')&amp;quot;)}" &gt;
                                &lt;xsl:value-of select="title"/&gt;
                            &lt;/a&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = true()"&gt;
                                &lt;xsl:call-template name="RSSMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:block;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = false()"&gt;
                                &lt;xsl:call-template name="RSSMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:none;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                    &lt;/div&gt;                            
                &lt;/xsl:if&gt;
            &lt;/xsl:for-each&gt;
        &lt;/xsl:template&gt;

    &lt;xsl:template name="RSSMainTemplate.description" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="DescriptionStyle"/&gt;
            &lt;xsl:param name="CurrentElement"/&gt;
        &lt;div id="{$CurrentElement}" class="description" align="{$rss_alignValue}" style="{$DescriptionStyle} text-align:{$rss_alignValue};"&gt;
                &lt;xsl:choose&gt;
                    &lt;!-- some RSS2.0 contain pubDate tag, some others dc:date --&gt;
                    &lt;xsl:when test="string-length(pubDate) &amp;gt; 0"&gt;
                        &lt;xsl:variable name="pubDateLength" select="string-length(pubDate) - 3" /&gt;
                &lt;xsl:value-of select="ddwrt:FormatDate(substring(pubDate,0,$pubDateLength),number($rss_LCID),3)"/&gt;
                    &lt;/xsl:when&gt;
                    &lt;xsl:otherwise&gt;
                        &lt;xsl:value-of select="ddwrt:FormatDate(string(dc:date),number($rss_LCID),3)"/&gt;
                    &lt;/xsl:otherwise&gt;
                &lt;/xsl:choose&gt;

                &lt;xsl:if test="string-length(description) &amp;gt; 0"&gt;
                    &lt;xsl:variable name="SafeHtml"&gt;
                        &lt;xsl:call-template name="GetSafeHtml"&gt;
                            &lt;xsl:with-param name="Html" select="description"/&gt;
                        &lt;/xsl:call-template&gt;
                    &lt;/xsl:variable&gt;
                     - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                &lt;/xsl:if&gt;
            &lt;div class="description"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(link))}"&gt;More...&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;/xsl:template&gt;


        &lt;xsl:template name="RDFMainTemplate" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:variable name="Rows" select="rss1:item"/&gt;
            &lt;xsl:variable name="RowCount" select="count($Rows)"/&gt;
            &lt;div class="slm-layout-main" &gt;
            &lt;div class="groupheader item medium"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(rss1:channel/rss1:link))}"&gt;
                    &lt;xsl:value-of select="rss1:channel/rss1:title"/&gt;
                &lt;/a&gt;
            &lt;/div&gt;            
            &lt;xsl:call-template name="RDFMainTemplate.body"&gt;
                &lt;xsl:with-param name="Rows" select="$Rows"/&gt;
                &lt;xsl:with-param name="RowCount" select="count($Rows)"/&gt;
            &lt;/xsl:call-template&gt;
            &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="RDFMainTemplate.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="Rows"/&gt;
            &lt;xsl:param name="RowCount"/&gt;
            &lt;xsl:for-each select="$Rows"&gt;
                &lt;xsl:variable name="CurPosition" select="position()" /&gt;
                &lt;xsl:variable name="RssFeedLink" select="$rss_WebPartID" /&gt;
                &lt;xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" /&gt;
                &lt;xsl:if test="($CurPosition &amp;lt;= $rss_FeedLimit)"&gt;
                    &lt;div class="item link-item" &gt;
                        &lt;a href="{concat(&amp;quot;javascript:ToggleItemDescription('&amp;quot;,$CurrentElement,&amp;quot;')&amp;quot;)}" &gt;
                            &lt;xsl:value-of select="rss1:title"/&gt;
                        &lt;/a&gt;
                        &lt;xsl:if test="$rss_ExpandFeed = true()"&gt;
                                &lt;xsl:call-template name="RDFMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:block;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                        &lt;/xsl:if&gt;
                        &lt;xsl:if test="$rss_ExpandFeed = false()"&gt;
                                &lt;xsl:call-template name="RDFMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:none;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                        &lt;/xsl:if&gt;
                    &lt;/div&gt;
        &lt;/xsl:if&gt;
            &lt;/xsl:for-each&gt;
        &lt;/xsl:template&gt;

    &lt;xsl:template name="RDFMainTemplate.description" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="DescriptionStyle"/&gt;
            &lt;xsl:param name="CurrentElement"/&gt;
        &lt;div id="{$CurrentElement}" class="description" align="{$rss_alignValue}" style="{$DescriptionStyle} text-align:{$rss_alignValue};"&gt;
            &lt;xsl:value-of select="ddwrt:FormatDate(string(dc:date),number($rss_LCID),3)"/&gt;
                &lt;xsl:if test="string-length(rss1:description) &amp;gt; 0"&gt;
                    &lt;xsl:variable name="SafeHtml"&gt;
                        &lt;xsl:call-template name="GetSafeHtml"&gt;
                            &lt;xsl:with-param name="Html" select="rss1:description"/&gt;
                        &lt;/xsl:call-template&gt;
                    &lt;/xsl:variable&gt;
                     - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                &lt;/xsl:if&gt;
            &lt;div class="description"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(rss1:link))}"&gt;More...&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;/xsl:template&gt;


        &lt;xsl:template name="ATOMMainTemplate" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:variable name="Rows" select="atom:entry"/&gt;
            &lt;xsl:variable name="RowCount" select="count($Rows)"/&gt;
            &lt;div class="slm-layout-main" &gt;
            &lt;div class="groupheader item medium"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(atom:link/@href))}"&gt;
                    &lt;xsl:value-of select="atom:title"/&gt;
                &lt;/a&gt;
            &lt;/div&gt;            
            &lt;xsl:call-template name="ATOMMainTemplate.body"&gt;
                &lt;xsl:with-param name="Rows" select="$Rows"/&gt;
                &lt;xsl:with-param name="RowCount" select="count($Rows)"/&gt;
            &lt;/xsl:call-template&gt;
            &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="ATOMMainTemplate.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="Rows"/&gt;
            &lt;xsl:param name="RowCount"/&gt;
            &lt;xsl:for-each select="$Rows"&gt;
                &lt;xsl:variable name="CurPosition" select="position()" /&gt;
                &lt;xsl:variable name="RssFeedLink" select="$rss_WebPartID" /&gt;
                &lt;xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" /&gt;
                &lt;xsl:if test="($CurPosition &amp;lt;= $rss_FeedLimit)"&gt;
                            &lt;div class="item link-item" &gt;
                                &lt;a href="{concat(&amp;quot;javascript:ToggleItemDescription('&amp;quot;,$CurrentElement,&amp;quot;')&amp;quot;)}" &gt;
                                    &lt;xsl:value-of select="atom:title"/&gt;
                                &lt;/a&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = true()"&gt;
                                &lt;xsl:call-template name="ATOMMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:block;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = false()"&gt;
                                &lt;xsl:call-template name="ATOMMainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:none;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                            &lt;/div&gt;
        &lt;/xsl:if&gt;
            &lt;/xsl:for-each&gt;
        &lt;/xsl:template&gt;

    &lt;xsl:template name="ATOMMainTemplate.description" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="DescriptionStyle"/&gt;
            &lt;xsl:param name="CurrentElement"/&gt;
        &lt;div id="{$CurrentElement}" class="description" align="{$rss_alignValue}" style="{$DescriptionStyle} text-align:{$rss_alignValue};"&gt;
        &lt;xsl:value-of select="ddwrt:FormatDate(string(atom:updated),number($rss_LCID),3)"/&gt;
                &lt;xsl:choose&gt;
                    &lt;xsl:when test="string-length(atom:summary) &amp;gt; 0"&gt;
                        &lt;xsl:variable name="SafeHtml"&gt;
                            &lt;xsl:call-template name="GetSafeHtml"&gt;
                                &lt;xsl:with-param name="Html" select="atom:summary"/&gt;
                            &lt;/xsl:call-template&gt;
                        &lt;/xsl:variable&gt;
                         - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                    &lt;/xsl:when&gt;
                    &lt;xsl:when test="string-length(atom:content) &amp;gt; 0"&gt;
                        &lt;xsl:variable name="SafeHtml"&gt;
                            &lt;xsl:call-template name="GetSafeHtml"&gt;
                                &lt;xsl:with-param name="Html" select="atom:content"/&gt;
                            &lt;/xsl:call-template&gt;
                        &lt;/xsl:variable&gt;
                         - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                    &lt;/xsl:when&gt;
                &lt;/xsl:choose&gt;
            &lt;div class="description"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(atom:link/@href))}"&gt;More...&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="ATOM2MainTemplate" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:variable name="Rows" select="atom2:entry"/&gt;
            &lt;xsl:variable name="RowCount" select="count($Rows)"/&gt;
            &lt;div class="slm-layout-main" &gt;
            &lt;div class="groupheader item medium"&gt;                
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(atom2:link/@href))}"&gt;
                    &lt;xsl:value-of select="atom2:title"/&gt;
                &lt;/a&gt;
            &lt;/div&gt;
            &lt;xsl:call-template name="ATOM2MainTemplate.body"&gt;
                &lt;xsl:with-param name="Rows" select="$Rows"/&gt;
                &lt;xsl:with-param name="RowCount" select="count($Rows)"/&gt;
            &lt;/xsl:call-template&gt;
            &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="ATOM2MainTemplate.body" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="Rows"/&gt;
            &lt;xsl:param name="RowCount"/&gt;
            &lt;xsl:for-each select="$Rows"&gt;
                &lt;xsl:variable name="CurPosition" select="position()" /&gt;
                &lt;xsl:variable name="RssFeedLink" select="$rss_WebPartID" /&gt;
                &lt;xsl:variable name="CurrentElement" select="concat($RssFeedLink,$CurPosition)" /&gt;
                &lt;xsl:if test="($CurPosition &amp;lt;= $rss_FeedLimit)"&gt;
                     &lt;div class="item link-item" &gt;
                                &lt;a href="{concat(&amp;quot;javascript:ToggleItemDescription('&amp;quot;,$CurrentElement,&amp;quot;')&amp;quot;)}" &gt;
                                    &lt;xsl:value-of select="atom2:title"/&gt;
                                &lt;/a&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = true()"&gt;
                                &lt;xsl:call-template name="ATOM2MainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:block;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                            &lt;xsl:if test="$rss_ExpandFeed = false()"&gt;
                                &lt;xsl:call-template name="ATOM2MainTemplate.description"&gt;
                                    &lt;xsl:with-param name="DescriptionStyle" select="string('display:none;')"/&gt;
                                    &lt;xsl:with-param name="CurrentElement" select="$CurrentElement"/&gt;
                                &lt;/xsl:call-template&gt;
                            &lt;/xsl:if&gt;
                    &lt;/div&gt;
        &lt;/xsl:if&gt;
            &lt;/xsl:for-each&gt;
        &lt;/xsl:template&gt;

    &lt;xsl:template name="ATOM2MainTemplate.description" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"&gt;
            &lt;xsl:param name="DescriptionStyle"/&gt;
            &lt;xsl:param name="CurrentElement"/&gt;
        &lt;div id="{$CurrentElement}" class="description" align="{$rss_alignValue}" style="{$DescriptionStyle} text-align:{$rss_alignValue};"&gt;
            &lt;xsl:value-of select="ddwrt:FormatDate(string(atom2:updated),number($rss_LCID),3)"/&gt;
                &lt;xsl:choose&gt;
                    &lt;xsl:when test="string-length(atom2:summary) &amp;gt; 0"&gt;
                        &lt;xsl:variable name="SafeHtml"&gt;
                            &lt;xsl:call-template name="GetSafeHtml"&gt;
                                &lt;xsl:with-param name="Html" select="atom2:summary"/&gt;
                            &lt;/xsl:call-template&gt;
                        &lt;/xsl:variable&gt;
                         - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                    &lt;/xsl:when&gt;
                    &lt;xsl:when test="string-length(atom2:content) &amp;gt; 0"&gt;
                        &lt;xsl:variable name="SafeHtml"&gt;
                            &lt;xsl:call-template name="GetSafeHtml"&gt;
                                &lt;xsl:with-param name="Html" select="atom2:content"/&gt;
                            &lt;/xsl:call-template&gt;
                        &lt;/xsl:variable&gt;
                         - &lt;xsl:value-of select="$SafeHtml" disable-output-escaping="yes"/&gt;
                    &lt;/xsl:when&gt;
                &lt;/xsl:choose&gt;
            &lt;div class="description"&gt;
                &lt;a href="{ddwrt:EnsureAllowedProtocol(string(atom2:link/@href))}"&gt;More...&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;/xsl:template&gt;

        &lt;xsl:template name="GetSafeHtml"&gt;
            &lt;xsl:param name="Html"/&gt;
            &lt;xsl:choose&gt;
                &lt;xsl:when test="$rss_IsDesignMode = 'True'"&gt;
                     &lt;xsl:value-of select="$Html"/&gt;
                &lt;/xsl:when&gt;
                &lt;xsl:otherwise&gt;
                     &lt;xsl:value-of select="rssaggwrt:MakeSafe($Html)"/&gt;
                &lt;/xsl:otherwise&gt;
            &lt;/xsl:choose&gt;
        &lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;
</property>
        <property name="EnableOriginalValue" type="bool">False</property>
        <property name="ExpandFeed" type="bool">False</property>
        <property name="ListUrl" type="string" null="true" />
        <property name="DataSourceID" type="string" />
        <property name="CacheXslTimeOut" type="int">600</property>
        <property name="ManualRefresh" type="bool">False</property>
        <property name="ViewFlags" type="Microsoft.SharePoint.SPViewFlags, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">None</property>
        <property name="ChromeState" type="chromestate">Normal</property>
        <property name="AllowHide" type="bool">True</property>
        <property name="ListDisplayName" type="string" null="true" />
        <property name="SampleData" type="string" null="true" />
        <property name="AsyncRefresh" type="bool">False</property>
        <property name="Direction" type="direction">NotSet</property>
        <property name="Title" type="string">RSS Viewer</property>
        <property name="ListId" type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">b60ccd97-c15a-462e-82e7-9684fa71d9a9</property>
        <property name="Description" type="string">Displays an RSS feed.</property>
        <property name="AllowMinimize" type="bool">True</property>
        <property name="TitleUrl" type="string" />
        <property name="DataSourcesString" type="string">
&lt;%@ Register TagPrefix="WebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %&gt;
&lt;%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %&gt;
&lt;WebControls:XmlUrlDataSource runat="server" AuthType="None" HttpMethod="GET"&gt;
  &lt;DataFileParameters&gt;
            &lt;WebPartPages:DataFormParameter Name="RequestUrl" ParameterKey="RequestUrl" PropertyName="ParameterValues"/&gt;
&lt;/DataFileParameters&gt;
&lt;/WebControls:XmlUrlDataSource&gt;</property>
        <property name="DisplayName" type="string" />
        <property name="PageType" type="Microsoft.SharePoint.PAGETYPE, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">PAGE_NORMALVIEW</property>
        <property name="Width" type="string" />
        <property name="AllowEdit" type="bool">True</property>
        <property name="ExportMode" type="exportmode">All</property>
        <property name="CacheRefreshTimeInMins" type="int">120</property>
        <property name="PageSize" type="int">-1</property>
        <property name="ViewContentTypeId" type="string" />
        <property name="HelpUrl" type="string" />
        <property name="XmlDefinition" type="string" />
        <property name="UseSQLDataSourcePaging" type="bool">True</property>
        <property name="TitleIconImageUrl" type="string" />
        <property name="MissingAssembly" type="string">Cannot import this web part.</property>
        <property name="HelpMode" type="helpmode">Modeless</property>
      </properties>
    </data>
  </webPart>
</webParts>\ 

Get WebPart Page of a SharePoint site using Web Services C#

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

 

Get the SchemaXml of a particular WebPart of a SharePoint Page using Web Services C#

In my previous post, https://realmpksharepoint.wordpress.com/2014/04/01/get-all-the-webparts-of-a-sharepoint-webpage-using-client-object-model-c/ , I have explained how to get WebParts properties. Now, if you’re interested in getting the schemaXml of that WebPart (like exporting a WebPart from the SharePoint Page in edit mode) then you can’t do that using CSOM. Here, the only available solution is the WebService, WebPartPages.asmx. You can view all the functions of this WebService at the url, YourSiteUrl/_vti_bin/WebPartPages.asmx.

What I am going to use here, is the method, GetWebPart2. This method takes three parameters, complete page Url, WebPartGuid, behavior-Shared/User.

string webPartInfo = String.Empty; 
string webServiceUrl = ctx.Web.Url + "/_vti_bin/WebPartPages.asmx";

//GetCompleteUrl is a custom utility function to append the web url and page //serverRelativeUrl.
string pageUrl = Utility.GetCompleteUrl(ctx.Web.Url, pageServerRelativeUrl);

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>" +
    "<GetWebPart2 xmlns=\"http://microsoft.com/sharepoint/webpartpages\">" +
        "<pageurl>{0}</pageurl>" +
        "<storageKey>{1}</storageKey>" +
        "<storage>{2}</storage>" +
        "<behavior>Version3</behavior>" +
    "</GetWebPart2>" +
"</soap:Body>"
, pageUrl, storageKey, "Shared"));
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/GetWebPart2\"");
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)
    webPartInfo = xDoc.DocumentElement.InnerText;

//webPartInfo is your WebParts SchemaXml.

Get all the WebParts of a SharePoint WebPage using Client Object Model C#

CSOM doesn’t have much to do with WebParts. However, you can modify certain properties like, Title. Below, I have demonstrated a simple way to get the WebParts of the page, Home, from the List, SitePages, of a TeamSite.
ClientContext ctx = new ClientContext(weburl);
ctx.Credentials = new SharePointOnlineCredentials(userName, passWord);

SP.List list = ctx.Web.Lists.GetByTitle("Site Pages");
ctx.Load(list);
CamlQuery cQuery = new CamlQuery();
ListItemCollection ltItemCollection = list.GetItems(cQuery);

ctx.Load(ltItemCollection);
ctx.ExecuteQuery();

ListItem ltItemHome = ltItemCollection.FirstOrDefault(p => p.DisplayName == "Home");

LimitedWebPartManager lwpmShared = ltItemHome.File.GetLimitedWebPartManager(PersonalizationScope.Shared);
LimitedWebPartManager lwpmUser = ltItemHome.File.GetLimitedWebPartManager(PersonalizationScope.User);

WebPartDefinitionCollection webPartDefinitionCollectionShared = lwpmShared.WebParts;
WebPartDefinitionCollection webPartDefinitionCollectionUser = lwpmUser.WebParts;

ctx.Load(webPartDefinitionCollectionShared, w => w.Include(wp => wp.WebPart, wp => wp.Id));
ctx.Load(webPartDefinitionCollectionUser, w => w.Include(wp => wp.WebPart, wp => wp.Id));
ctx.Load(ltItemHome.File);
ctx.Load(ctx.Web, p => p.Url);
ctx.ExecuteQuery();
 
foreach (WebPartDefinition webPartDefinition in webPartDefinitionCollectionShared)
{
    WebPart webPart = webPartDefinition.WebPart;
    ctx.Load(webPart, wp => wp.ZoneIndex, wp => wp.Properties, wp => wp.Title, wp => wp.Subtitle, wp => wp.TitleUrl);
    ctx.ExecuteQuery();
    
    //Once the webPart is loaded, you can do your modification as follows
    webPart.Title = "My New Web Part Title";
    webPartDefinition.SaveWebPartChanges();
    ctx.ExecuteQuery();
}

To get the SchemaXml of a particular WebPart of a SharePoint Page using Web Services, visit the following link,
https://realmpksharepoint.wordpress.com/2014/04/03/get-the-schemaxml-of-a-particular-webpart-of-a-sharepoint-page-using-web-services-c/