O365 / SharePoint Online – Apply Theme – CSOM & Powershell

As you know, Web.ApplyTheme method applies a theme with the specified components to this site.

For more information refer – https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.web.applytheme.aspx

Here fontSchemeUrl and backgroundImageUrl parameters can accept null values. But when I tried to pass $null or null or Empty String to these two parameters via PowerShell, I got the following error:

“Exception calling “ApplyTheme” with “4” argument(s): “The ‘fontSchemeUrl’ argument is invalid.”.Exception.Message”

Then i tried with Out-Null instead of $null or null or Empty String. Trust me it worked like a charm.

Actually the Out-Null cmdlet deletes output instead of sending it down the pipeline.

This is my final code.

Hope it helps 🙂

Fixed

 

 

How to read SharePoint Managed Metadata Look-up (Taxonomy Field) value using Client Object Model?

The below Console Application code explains you how to read SharePoint Managed Metadata Look-up (Taxonomy Field) value using Client Object Model.

using System;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Taxonomy;

namespace CSOMRnD
{
class Program
{
static void Main(string[] args)
{

using (ClientContext context = new ClientContext("SiteURL"))
{
context.ExecutingWebRequest += new EventHandler(clientContext_ExecutingWebRequest);
context.AuthenticationMode = ClientAuthenticationMode.Default;
context.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

List list = context.Web.Lists.GetByTitle("ListName");

CamlQuery query = new CamlQuery();

query.ViewXml = "pass your query";

ListItemCollection items = list.GetItems(query);
context.Load(items);
context.ExecuteQuery();

foreach (ListItem item in items)
{
StringBuilder sb_ProductFieldValue = new StringBuilder();

TaxonomyFieldValueCollection taxProductFieldValueColl = item["Product"] as TaxonomyFieldValueCollection;

if (taxProductFieldValueColl != null)
{
foreach (TaxonomyFieldValue taxProductFieldValue in taxProductFieldValueColl)
{
if (taxProductFieldValue.Label.Trim() != null)
sb_ProductFieldValue.Append(taxProductFieldValue.Label + "|");
else
sb_ProductFieldValue.Append("Empty");
}
}
Console.WriteLine(sb_ProductFieldValue.ToString());
}
Console.ReadLine();
}
}

static void clientContext_ExecutingWebRequest(object sender, WebRequestEventArgs e)
{
e.WebRequestExecutor.WebRequest.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
}

}
}

Simple Watermark function for HTML Inputbox

One of the simplest way to create Watermark functionality for the HTML Input control 

<input
type=”text”
value=”Search Wiki”
name=”visitors_name”
onblur=”if(value==”) value = ‘Search Wiki'”
onfocus=”if(value==’Search Wiki’) value = ””
/>

Searching SharePoint Results from Windows Explorer using OSDX and Custom RSS File

Environment:

SharePoint 2013 Enterprise Search with Windows 7 Operating Systems

Introduction:

To understand what is a OSDX file and how to add an OSDX file as a search provider in Windows Explorer please refer the below links:

https://www.nothingbutsharepoint.com/sites/eusp/Pages/sharepoint-2010-search-locations-in-windows-7.aspx

http://technet.microsoft.com/en-us/library/ff899315(v=office.14).aspx

Problem:

When I use the OOB SharePoint RSS file to show the results in the windows explorer I was not able to map the custom managed properties to the windows attributes such as Summary,  thumbnail, etc.,

The OOB SharePoint RSS file located in the following location:

http://<Site>/_layouts/srchrss.aspx

Regarding this issue, when I approached some MVPs and Microsoft Windows Development team they replied that it is not possible to map the SharePoint managed properties with the windows explorer search result attributes.

Some of the articles are also explaining the same

http://msdn.microsoft.com/en-us/library/dd742951(v=VS.85).aspx

https://communities.netapp.com/blogs/TheSharePointGuy/2011/09/22/windows-7-sharepoint-search-connector

So what is the solution for this?

Solution:

Windows 7 is the first OS with the capability to use external search providers as federated search locations – and yes, this federated location can also be SharePoint!  In general, all search providers can be federated if it’s OpenSearch 1.0/1.1 compatible or, in other words, can provide the search results in RSS/Atom format.

So that means if I have to create my own RSS feeding file then my custom code should return the SharePoint search results in RSS/Atom format. So I started exploring what is the best way to get the search results. Then I found a interesting feature in SharePoint 2013 called “SharePoint 2013 Search REST API”. This new REST service is the best way to go in a variety of application scenarios. External Applications to SharePoint that require search functionality can also leverage this service as the endpoint for communication into the Search platform. The old search.asmx SOAP web service is marked as deprecated in SP2013, and the new Search REST service is the replacement.

Location of the Search Rest service

The Search REST service is located at the following URI: http://host/site/_api/search

See more about this from the below link

http://blogs.msdn.com/b/nadeemis/archive/2012/08/24/sharepoint-2013-search-rest-api.aspx

Using the above mentioned API I am supplying the keyword to the API and getting the XML output. From the XML output I am extracting the necessary XML Node values and populating the output in the format of RSS/Atom using the below code:

Front end Code

<%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”SearchAppliedRSS.aspx.cs” Inherits=”SearchResultsRSS.Layouts.SearchResultsRSS.SearchAppliedRSS” ContentType=”text\xml” %>

<asp:Repeater ID=”ResultRSSRepeater” runat=”server”>

<HeaderTemplate>

<rss version=”2.0″>

<channel>

<title>Nucleus</title>

<link>Configure you site URL</link>

<description>

Nucleus Search Center Site.

</description>

</HeaderTemplate>

<ItemTemplate>

<item>

<title><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Title”)) %></title>

<link>Item URL</link>

<description><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Description”))%></description>

<category><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Category”)) %></category>

<pubDate><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “LastModifiedTime”))%></pubDate>

<author><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, “Author”))%></author>

</item>

</ItemTemplate>

<FooterTemplate>

</channel>

</rss>

</FooterTemplate>

</asp:Repeater>

Back end Code

protected void Page_Load(object sender, EventArgs e)

{

string keyword = Request.QueryString[“keyword”];

string query = “http://<Site Name>/_api/search/query?querytext='” + keyword + “‘&sourceid=’c9a51276-5b58-423c-88cb-a64297974cb4’&selectproperties=’Author,TCItemType,TCItemName,Description,LastModifiedTime'”;

WebRequest req = WebRequest.Create(query);

NetworkCredential myCred = new NetworkCredential(“<Admin Account User ID>”,”Password”,”Domain Name”);

req.Credentials = myCred;

WebResponse resp = req.GetResponse();

System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());

// process response..

XDocument oDataXML = XDocument.Load(sr, LoadOptions.None);

XNamespace atom = “http://www.w3.org/2005/Atom&#8221;;

XNamespace d = “http://schemas.microsoft.com/ado/2007/08/dataservices&#8221;;

XNamespace m = “http://schemas.microsoft.com/ado/2007/08/dataservices/metadata&#8221;;

List<XElement> items = oDataXML.Descendants(d + “query”)

.Elements(d + “PrimaryQueryResult”)

.Elements(d + “RelevantResults”)

.Elements(d + “Table”)

.Elements(d + “Rows”)

.Elements(d + “element”)

.ToList();

// Extracting the values from XML..

DataTable dt = new DataTable();

dt.Columns.Add(“Title”);

dt.Columns.Add(“Author”);

dt.Columns.Add(“Category”);

dt.Columns.Add(“Description”);

dt.Columns.Add(“LastModifiedTime”);

foreach (XElement item in items)

{

DataRow dr = dt.NewRow();

//XElement xItem = item.Element(d + “Cells”).Descendants(d + “Key”).First();

foreach (XElement xItem in item.Element(d + “Cells”).Descendants(d + “Key”))

{

if (xItem.Value == “TCItemName”)

{

dr[“Title”] = xItem.Parent.Element(d + “Value”).Value;

}

else if (xItem.Value == “Author”)

{

dr[“Author”] = xItem.Parent.Element(d + “Value”).Value;

}

else if (xItem.Value == “Description”)

{

dr[“Description”] = xItem.Parent.Element(d + “Value”).Value;

}

else if (xItem.Value == “LastModifiedTime”)

{

dr[“LastModifiedTime”] = xItem.Parent.Element(d + “Value”).Value;

}

dr[“Category”] = “Teamcenter Item”;

}

dt.Rows.Add(dr);

}

// data-bind to ListView..

ResultRSSRepeater.DataSource = dt;

ResultRSSRepeater.DataBind();

}

protected string RemoveIllegalCharacters(object input)

{

// cast the input to a string

string data = input.ToString();

// replace illegal characters in XML documents with their entity references

data = data.Replace(“&”, “&amp;”);

data = data.Replace(“\””, “&quot;”);

data = data.Replace(“‘”, “&apos;”);

data = data.Replace(“<“, “&lt;”);

data = data.Replace(“>”, “&gt;”);

return data;

}

Finally instead of configuring the SharePoint OOB search RSS file, I have configured the customized RSS Feed file which I have created using the above code in the OSDX file.

How to create RSS?

http://net.tutsplus.com/tutorials/asp-net/how-to-build-an-rss-feed-with-asp-net/

Now I am able to see the results with the format I have specified in the code. Please see the below screen:

search-result-in-we

Load alternate image if there is an error in the configured image URL – IMG Tag

Requirement:

We have a SharePoint BCS Profile page (with XSLT customization). In this page we have to load an image in one of the column/cell. There is no problem in loading the image with the IMG tag until the image is not available. If the image is not available in the given URL, it will normally show the cross mark (X) symbol.

The customer requirement is below:

If the image is not available in the given URL location then show an alternative image / text (Preview not Available).

Solution:  

By adding the below tag you can overcome this issue

<img src=”<Image URL>” alt=”” onError=”this.src=<Alternate Image URL>’/>

We have to be very cautious when we use this code. The browser will be stuck in an endless loop if the onError alternate image itself gives an error in loading. So to avoid this use the below code

<img src=”<Image URL>” alt=”” onError=”this.onerror=null;this.src=<Alternate Image URL>’/>

Displaying Current User Display Name in SPD Custom Forms

  • Open the custom page in Advanced Mode using SharePoint Designer
  • Find the section of the page where “ParameterBinding” are set. Add this new entry:  <ParameterBinding> Name = “LogonUser” Location = “ServerVariable(LOGON_USER)” />
  • Next search for “XSL:Param name”, and add this line: <xsl:param name=”LogonUser”/>
  • Now to display the value in the form use the below tag where ever you want: <xsl:value-of select=”$LogonUser”/>

Redirecting SPD NewForm.aspx to other pages with the Current Item ID as Query String

Business Need

We have a site request SharePoint List. Users will raise request using this list to get a new SharePoint WIKI article. Once the user press the Save button in the OOB SharePoint Designer form (which we customized using SPD 2010), it should redirect to one Status Page and wait there till the workflow creates the new site and configure the permission based on the meta data submitted by the requestor.

Once the workflow is completed we have to check the status of the workflow. If the status of the workflow is “Success” then we have to redirect the page to the newly created site. If the status is “Failed” then we have to show an alert message.

Problem

Basically in SPD forms once the data is submitted, the page will be redirected to the page where you came from.

The problem here is to identify the ID of the newly created item and check the workflow status using that ID since the ID for the new item is unknown before the item has been created

Solution

To solve this we have to follow the below steps explained in the below article :

http://sympmarc.com/2009/06/12/redirect-to-another-page-from-newform-aspx-with-the-new-items-id/

Steps

First Open the customized New / Edit form in SPD 2010 and override the SharePoint default save buttons with the HTML input buttons

<input type=”button” value=”Save” name=”btnSave” onclick=”javascript: {ddwrt:GenFireServerEvent(‘__commit;__redirect={/Sites/<Site Name>/<Library Name>/GetLastID.aspx?RedirectURL=/Sites/<Site Name>/<Library Name>/WIKIStatus.aspx}’)}” />

Note: Replace the Site Name and Library Name with your details

Now create an intermediate page (GetLastID.aspx) and paste the below code then upload this in any of your document library of your site.  All this page does is find the most recent item in the list which was created by the current user and redirect to WIKIStatus.aspx with the ID on the Query String (ParaID).

<%@ Page Language=”C#” inherits=”Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Register Tagprefix=”SharePoint” Namespace=”Microsoft.SharePoint.WebControls” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Register Tagprefix=”Utilities” Namespace=”Microsoft.SharePoint.Utilities” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<%@ Import Namespace=”Microsoft.SharePoint” %>

<%@ Register Tagprefix=”WebPartPages” Namespace=”Microsoft.SharePoint.WebPartPages” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

<html>

<head runat=”server”>

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>

</head>

<body>

<form id=”form1″ runat=”server”>

<WebPartPages:DataFormWebPart runat=”server” IsIncluded=”True” FrameType=”None” NoDefaultStyle=”TRUE” ViewFlag=”0″ Title=”Events” __markuptype=”vsattributemarkup” __WebPartId=”{020AF483-2135-4D37-B6C7-CD6A6FD6AF5D}” id=”g_a8a4d070_e7c0_4105_a113_acff9dea3328″ pagesize=”1″ __AllowXSLTEditing=”true” WebPart=”true” Height=”” Width=””>

<DataSources>

<SharePoint:SPDataSource runat=”server” DataSourceMode=”List” UseInternalName=”true” selectcommand=”<View><Query><Where><Eq><FieldRef Name=&quot;Author&quot;/><Value Type=&quot;Integer&quot;><UserID/></Value></Eq></Where><OrderBy><FieldRef Name=&quot;Created_x0020_Date&quot; Ascending=&quot;FALSE&quot;/></OrderBy></Query></View>” id=”dataformwebpart2″>

<SelectParameters>

<WebPartPages:DataFormParameter Name=”ListName” ParameterKey=”ListName” PropertyName=”ParameterValues” DefaultValue=”Test List”/>

</SelectParameters>

</SharePoint:SPDataSource>

</DataSources>

<parameterbindings>

<ParameterBinding Name=”UserID” Location=”CAMLVariable” DefaultValue=”CurrentUserName”/>

<ParameterBinding Name=”RedirectURL” Location=”QueryString(RedirectURL)” DefaultValue=””/>

</parameterbindings>

<datafields>@Title,Title;@Start_x0020_Time,Start Time;@End_x0020_Time,End Time;@ZIP_x0020_Code,ZIP Code;@Amount,Amount;@Nominee,Nominee;@ID,ID;@ContentType,Content Type;@Modified,Modified;@Created,Created;@Author,Created By;@Editor,Modified By;@_UIVersionString,Version;@Attachments,Attachments;@File_x0020_Type,File Type;@FileLeafRef,Name (for use in forms);@FileDirRef,Path;@FSObjType,Item Type;@_HasCopyDestinations,Has Copy Destinations;@_CopySource,Copy Source;@ContentTypeId,Content Type ID;@_ModerationStatus,Approval Status;@_UIVersion,UI Version;@Created_x0020_Date,Created;@FileRef,URL Path;</datafields>

<XSL>

<xsl:stylesheet xmlns:x=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:d=”http://schemas.microsoft.com/sharepoint/dsp&#8221; version=”1.0″ exclude-result-prefixes=”xsl msxsl ddwrt” xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime&#8221; xmlns:asp=”http://schemas.microsoft.com/ASPNET/20&#8243; xmlns:__designer=”http://schemas.microsoft.com/WebParts/v2/DataView/designer&#8221; xmlns:xsl=”http://www.w3.org/1999/XSL/Transform&#8221; xmlns:msxsl=”urn:schemas-microsoft-com:xslt” xmlns:SharePoint=”Microsoft.SharePoint.WebControls” xmlns:ddwrt2=”urn:frontpage:internal”>

<xsl:output method=”html” indent=”no”/>

<xsl:param name=”UserID”>CurrentUserName</xsl:param>

<xsl:param name=”RedirectURL” />

<xsl:template match=”/” xmlns:x=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:d=”http://schemas.microsoft.com/sharepoint/dsp&#8221; xmlns:asp=”http://schemas.microsoft.com/ASPNET/20&#8243; xmlns:__designer=”http://schemas.microsoft.com/WebParts/v2/DataView/designer&#8221; xmlns:SharePoint=”Microsoft.SharePoint.WebControls”>

<xsl:call-template name=”dvt_1″/>

</xsl:template>

<xsl:template name=”dvt_1″>

<xsl:variable name=”Rows” select=”/dsQueryResponse/Rows/Row”/>

<xsl:for-each select=”$Rows”>

<xsl:call-template name=”dvt_1.rowview” />

</xsl:for-each>

</xsl:template>

<xsl:template name=”dvt_1.rowview”>

<script type=”text/javascript”>

document.location.href = &apos;<xsl:value-of select=”$RedirectURL” />&apos; +

&quot;?ParaID=&quot; + &apos;<xsl:value-of select=”@ID” />&apos;;

</script>

</xsl:template>

</xsl:stylesheet>

</XSL>

</WebPartPages:DataFormWebPart>

</form>

</body>

</html>

Note: Replace “Test List” with your list name

Now create a new page and name it as “WIKIStatus” and add the below script in a CEWP. All this CEWP page does is check the status of the workflow for the Item Id received from the Query String.  If the value of the status column is “Success” then it will redirect the page to the newly created site (which was updated by the workflow behind the scene). If the status is “Failed”, then it will show an alert message.

<script type=”text/javascript” language=”javascript”>

ExecuteOrDelayUntilScriptLoaded(runCode, “sp.js”);

var itemId = querySt(“ParaID”);   // Query String

var targetListItem;

function runCode()

{

var clientContext = new SP.ClientContext();

var targetList = clientContext.get_web().get_lists().getByTitle(‘Test List’); // Change the List Name here

targetListItem = targetList.getItemById(itemId);

clientContext.load(targetListItem, ‘Status’, ‘SiteURL’); // Select the column names here

clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));

}

function onQuerySucceeded()

{

if(targetListItem.get_item(‘Status’) != “Completed” || targetListItem.get_item(‘Status’) != “Failed” )

{

queryList();

}

if(targetListItem.get_item(‘Status’) == “Completed”)

{

document.location.href = targetListItem.get_item(‘SiteURL’);

}

if(targetListItem.get_item(‘Status’) == “Failed”)

{

alert(“Please contact the administrator.”);

}

}

function onQueryFailed(sender, args)

{

// alert(‘Request failed. \nError: ‘ + args.get_message() + ‘\nStackTrace: ‘ + args.get_stackTrace());

alert(‘Request failed. \n Contact Admin ‘);

}

function querySt(Key)

{

var url = window.location.href;

KeysValues = url.split(/[\?&]+/);

for (i = 0; i < KeysValues.length; i++)

{

KeyValue= KeysValues[i].split(“=”);

if (KeyValue[0] == Key)

{

return KeyValue[1];

}

}

}

function queryList()

{

window.setTimeout(“runCode()”, 5000);

}

</script>

<div id=”divload” style=”background-image: url(/sites/jrdw/shared%20documents/ajax_loader_blue_48.gif); width: 64px; background-repeat: no-repeat; height: 64px”></div>

Note: 

1)      Replace “Test List” with your list name

2)      “Status” and “SiteURL” are the two columns iam refereing from my site request list

That’s it you are done 🙂 . Thank you Marc for the idea you have explained in your article.