Upload Large Files to the SharePoint DocumentLibrary using RPC from a Desktop Application C#

In one of my previous post, https://realmpksharepoint.wordpress.com/2014/01/19/upload-a-file-to-sharepoint-using-client-object-model/ , I had shown how we can upload documents to SharePoint using CSOM. Though, the client object model was working perfectly for smaller documents, it started throwing time-out errors when I tried to upload a file of size around 40MB (previously, I was uploading documents < 2MB).

So to upload large documents I am going to use RPC. RPC is an interprocess communication technique that allows client and server software to communicate. For more details of RPC you can visit WikiPedia and TechNet articles.

public void UploadFile(string currentWebUrl, string serviceName, string filePath, FileStream stream, string userDomainName)
{
    newFileData = null;
    newFileData = new byte[stream.Length];
    stream.Read(newFileData, 0, Convert.ToInt32(stream.Length));
    string requestUrl = currentWebUrl + "/_vti_bin/_vti_aut/author.dll";
    string method = GetEncodedString("put document:15.0.0.4420");
    serviceName = GetEncodedString("/" + serviceName);
    
    string putOption = "overwrite";
    string metaInfo = "[vti_modifiedby;SW|" + userDomainName + ";vti_author;SW|" + userDomainName + "]]";
    string comments = GetEncodedString("File uploaded using RPC call");
    string docDetails = String.Format("[document_name={0};meta_info={1}", filePath, metaInfo);
    docDetails = GetEncodedString(docDetails);
    rpcCallString = "method={0}&service_name={1}&document={2}&put_option={3}&comment={4}&keep_checked_out=false\n";
    rpcCallString = String.Format(rpcCallString, method, serviceName, docDetails, putOption, comments).Replace("_", "%5f");
    
    HttpWebRequest wReq = WebRequest.Create(requestUrl) as HttpWebRequest;
    wReq.Method = "POST";
    wReq.Headers["Content"] = "application/x-vermeer-urlencoded";
    wReq.Headers["X-Vermeer-Content-Type"] = "application/x-vermeer-urlencoded";
    wReq.UserAgent = "FrontPage";
    wReq.UseDefaultCredentials = false;
    
    Uri targetSite = new Uri(this.ctx.Web.Url);



//Get the credential for authentication
    SharePointOnlineCredentials spCredentials = (SharePointOnlineCredentials)this.ctx.Credentials;

//Retrieve the authentication cookie with the help of credentials
    string authCookieValue = spCredentials.GetAuthenticationCookie(targetSite);
    wReq.CookieContainer = new CookieContainer();
    wReq.CookieContainer.Add(
        new Cookie("FedAuth",
            authCookieValue.TrimStart("SPOIDCRL=".ToCharArray()),
            String.Empty,
            targetSite.Authority));

    wReq.BeginGetRequestStream(new AsyncCallback(gotRequestStream), wReq);
}

private void gotRequestStream(IAsyncResult asynchronousResult)
{
    HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
    Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);
    List<byte> uploadData = new List<byte>();
    uploadData.AddRange(Encoding.UTF8.GetBytes(rpcCallString));
    uploadData.AddRange(newFileData);
    
    byte[] fileData = uploadData.ToArray();
    requestStream.Write(fileData, 0, fileData.Length);
    requestStream.Close();
    webRequest.BeginGetResponse(new AsyncCallback(gotResponse), webRequest);
}

private void gotResponse(IAsyncResult asynchronousResult)
{
    HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
    HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
    Stream responseStream = webResponse.GetResponseStream();
    StreamReader reader = new StreamReader(webResponse.GetResponseStream());
    
    string responseString = String.Empty;
    responseString = reader.ReadToEnd();
    byte[] fileBuffer = Encoding.UTF8.GetBytes(responseString);
    responseStream.Close();
    reader.Close();
    webResponse.Close();
    
    if (responseString.IndexOf("\n
message=successfully"

) < 0)
    {
        //Indicates that the SharePoint has returned an error message. The document might have got uploaded also so one should better check the message first.
        throw new Exception(responseString);
    }
}

Now, let’s evaluate this.

  • Here we are using the method, “put document” and, “15.0.0.4420” is server extension version.
  • Service name is server relative URL of your site.
  • In document parameter we are providing to fields “document_name” and “meta_info”. Document name is the path at which we want to upload the file including the file name and meta info sets the metadata of the document to be uploaded. MetaInfo is a system site-column where SharePoint stores custom values related to that particular ListItem.
  • Next parameter is put_option where you can provide “overwrite” if you want to overwrite existing file with same name else you can provide “edit”.
  • Next two parameters comment and keep_checked_out are very straight forward.
  • For authentication, we’re using the CookieContainer of HTTPWebRequest.

In case of RPC calls it is confusing how to pass parameters, mostly in case of file paths. So here is the example of how will you call this upload method.

UploadFile("http://myserver/sites/teamsite/", "sites/teamsite", "Shared Documents/document1.docx", fileStream, "Piyush Singh");

One utility method has been used here for encoding of string. Here it is for the reference.

public string GetEncodedString(string sourceString)
{
    if (!String.IsNullOrEmpty(sourceString))
    { 
        return HttpUtility.UrlEncode(sourceString).Replace(".", "%2e").Replace("_", "%5f");
    }
    else
    {
        return sourceString;
    }
}

You can get more info about put document here, http://msdn.microsoft.com/en-us/library/ms479623.aspx.

It has been said that in this way we can upload document up to 2GB to the site. Well, I have tested it for the documents of size little over 100MB and it’s working fine.

Also, you can visit the following post to upload files up to 10GB to SharePoint Online,

https://realmpksharepoint.wordpress.com/2016/07/22/upload-large-files-to-sharepoint-online/.

Add a new User to the User Information List from the Office365 Active User Panel using Client Object Model C#

This post is about a hidden List of SharePoint, User Information List. In this, the items are the active Office365 users, that have some interaction with this site. For ex. if a user has visited the site, or, the user has been marked in one of the List [like assigned a Task] of the site, or, the user is the administrator then, the user gets automatically added to this List.

By default, the site’s administrator is the only added user to this List. So, if you assign say, a task, to an active user from the Office365 user panel, then, SharePoint automatically adds the user in the User Information List. In my one of the earlier post, https://realmpksharepoint.wordpress.com/2014/01/19/update-a-usermulti-column-value-in-client-object-model-c/, I had demonstrated how to update a UserField SiteColumn say, Attendees for a Calendar item[meeting], with the user id from the web’s SiteUsers. However, we only get the users from the User Information List as the SiteUsers in CSOM.

So how to add a new active user to this List using CSOM? The answer is the EnsureUser method.
It adds the valid user to the site if it’s not already added.

User user = clientContext.Web.EnsureUser("Piyush Singh");
clientContext.Load(user);
clientContext.ExecuteQuery();

Get the CultureInfo of a SharePoint Online site using Client Object Model C#

CSOM code gets executed from client machine and there’s a fair amount of chance that the current machine culture will not match with that of SharePoint Online site. Now, the problem is that for a ListItem of any List, SharePoint returns DateTime value in a string format. So, if you try to convert the string to a DateTime, you’ll get a FormatException that, the String was not recognized as a valid DateTime.

So, the solution is to get the current culture of the SharePoint Online site, and then apply the same to the current thread. To do that you need to query the LocaleId of the current site which, you can then use to get the CultureInfo.

//Getting and applying the SharePoint site culture to the working thread 
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(Convert.ToInt32(ctx.Web.RegionalSettings.LocaleId));

I have successfully tested this code for the following two conditions. My machine’s culture was en-US [MM/DD/YYYY] :-

  • en-CA [DD/MM/YYYY]
  • en-ZA [YYYY/MM/DD]

You can also see the List of CultureInfo.

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>\