Showing posts with label csom. Show all posts
Showing posts with label csom. Show all posts

Tuesday, October 28, 2014

How to change the number of decimal places on a number column using CSOM

Got a challenge for a one liner by the strongest man in SharePoint (@tarjeieo) to do this using CSOM as with with SSOM you can set the DisplayFormat property of the field. Using CSOM, this property is not available.

A one liner would be ugly, but the way to accomplish this is to modify the SchemaXml of the field, so you could encapsulate the code below in a function.

Using XML manipulation I ended up with this.

ClientContext clientContext = new ClientContext("https://site/);
Web web = clientContext.Web;
Field field = web.Fields.GetByTitle("DummyNum"); // Field to modify
clientContext.Load(field);
clientContext.ExecuteQuery();
XmlDocument doc = new XmlDocument();
doc.LoadXml(field.SchemaXml);
XmlNode fieldNode = doc.SelectSingleNode("Field");
XmlAttribute decimalAttribute = fieldNode.Attributes["Decimals"];
if (decimalAttribute == null)
{
decimalAttribute = doc.CreateAttribute("Decimals");
fieldNode.Attributes.Append(decimalAttribute);
}
decimalAttribute.Value = "4";
field.SchemaXml = doc.OuterXml;
field.UpdateAndPushChanges(true);
clientContext.ExecuteQuery();

Thursday, October 16, 2014

Retrieving and working with Search Navigation entries using CSOM

I’m currently working on some provisioning tasks for a search page and we want to script up the search navigation using CSOM. This would be the Everything, People, and Social tabs you see below the search box.
The issue is that Web.Navigation does not have the SearchNav property which SPWeb.Navigation has. It only has QuickLaunch and TopNavigationBar.
But just because the good guys over at Microsoft haven’t gotten around to implement all the SSOM properties doesn’t mean we’re stuck. Using Reflector I figured out the node id for the search navigation was 0x410. Which yields the following code.
string siteUrl = "http://dev/sites/search";

ClientContext clientContext = new ClientContext(siteUrl);
Web web = clientContext.Web;

var nav = web.Navigation;

NavigationNode searchNav = nav.GetNodeById(1040);
NavigationNodeCollection nodeCollection = searchNav.Children;

clientContext.Load(nodeCollection);
clientContext.ExecuteQuery();

foreach (NavigationNode navigationNode in nodeCollection)
{
    Console.WriteLine(navigationNode.Title + " : " + navigationNode.Url);
}

Take a look at http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.navigationnodecollection(v=office.15).aspx for sample code on how to add more nodes to the collection.

Enjoy!

Friday, September 26, 2014

How To: Query the Office Graph using CSOM

I’m in the process of adding GQL support to the SharePoint 2013 Search Query Tool together with Barry Waldbaum (Microsoft), and while writing the POST support I found it easier to test it using CSOM.

image

Below is sample code with inline comments if you want to go the CSOM route instead of using REST to query the Office graph. The key is to use the Properties property of the KeywordQuery object.

The benefit of using CSOM over REST in my opinion is that you can pass in more than one query per call, and thus optimize network traffic and wire chatter.

Tuesday, April 22, 2014

Adding a content type to a list using CSOM in JavaScript throws “Collection has not been initialized” error

My colleague Janaka at Puzzlepart is writing a CSOM PowerShell script to add a content type to a custom list. Doing this he stumbled upon an interesting/weird error.
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl)
$clientContext.Credentials = $credentials
$site = $clientContext.Site;
$web = $site.RootWeb;           
$ct = $web.ContentTypes.GetById("0x0100FE72F7843250314FB0ED7A98DCE072C1")
$clientContext.Load($site)
$clientContext.Load($web)
$clientContext.Load($ct)
$list = $web.Lists.GetByTitle("Test One")
$cts = $list.ContentTypes
$clientContext.Load($cts)
$cts.AddExistingContentType($ct)
$clientContext.ExecuteQuery()

Once you execute the above code in a function, line 12 will throw the following error and stop your script.

format-default : The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.
+ CategoryInfo          : NotSpecified: (:) [format-default], CollectionNotInitializedException
+ FullyQualifiedErrorId : Microsoft.SharePoint.Client.CollectionNotInitializedException,Microsoft.PowerShell.Comma   nds.FormatDefaultCommand

Wednesday, December 11, 2013

Duplicate Trimming in SharePoint 2013 is causing confusion

[Update - Verified with July 2014 CU]
You can now turn off security trimming via the Query Builder on your search web parts.

  • Edit web part
  • Click "Change query"
  • Click the "Settings" tab
  • Toggle "Don't remove duplicates'


[Original Post]
Duplicate trimming as a function in search is a good idea. The intent is to reduce noise by discarding duplicate or equal items in a search result. The issue with SharePoint 2013 is that trimming is implemented too coarse and a lot of good results are hidden for the user. Also, turning off duplicate trimming is not an edit web part task as the option is hidden in a JSON property on the web part.

My recommendation at the moment is to turn off duplicate trimming, and if users complain about real duplicates being show, tell them to clean up the data. Most of the time you really don’t want duplicates of items/documents stored anyways.

I’ll dig into and explain more about how duplicate trimming is performed in SharePoint 2013 in a later post.

If you are on-premises you may use the same procedure as I used in Make sure your People Search is fuzzified, where using PowerShell, you modify the internal JSON property. Using the same script change line 13 to read:

$dataProvider.TrimDuplicates = false

Being inspired by Chris O’Brian’s post on using CSOM with PowerShell I have modified my code to use PowerShell  and CSOM. By changing the credentials line, you may use the code against both SharePoint on-premises and SharePoint on-line.

# Author: Mikael Svenson - @mikaelsvenson
# Company: Puzzlepart
# Date: December, 2013
# Reference: http://www.sharepointnutsandbolts.com/2013/12/Using-CSOM-in-PowerShell-scripts-with-Office365.html

# replace these details (also consider using Get-Credential to enter password securely as script runs).. 
$username = "username@something.onmicrosoft.com" 
$password = "password" 
$url = "https://company.sharepoint.com/search"
# the path to the SharePoint Client dlls' 
$dllPath = "D:\SP2013-dll\ISAPI\"
 
$securePassword = ConvertTo-SecureString $Password -AsPlainText -Force 
 
Add-Type -Path "$($dllPath)Microsoft.SharePoint.Client.dll" 
Add-Type -Path "$($dllPath)Microsoft.SharePoint.Client.Runtime.dll" 
Add-Type -Path "$($dllPath)Microsoft.SharePoint.Client.Publishing.dll"
Add-Type -Path "$($dllPath)Microsoft.SharePoint.Client.Taxonomy.dll" 
 
# connect/authenticate to SharePoint Online and get ClientContext object.. 
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url) 

#$credentials = New-Object System.Net.NetworkCredential($username, $securePassword) 
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword) 
$clientContext.Credentials = $credentials 
 
if (!$clientContext.ServerObjectIsNull.Value) 
{ 
    Write-Host "Connected to SharePoint site: '$Url'" -ForegroundColor Green 
} 

$web = $clientContext.Web
$clientContext.Load($web.AllProperties)
$clientContext.ExecuteQuery()
# get guid of the default Pages library to cater for localization
$pagesGuid = $web.AllProperties.FieldValues["__PagesListId"]
$clientContext.ExecuteQuery()
$clientContext.Load($web.Lists)
$list = $web.Lists.GetById($pagesGuid)
$clientContext.Load($list)
$clientContext.Load($list.RootFolder)
$clientContext.ExecuteQuery()
# get localized server relative url
$url = $list.RootFolder.ServerRelativeUrl

$page = $web.GetFileByServerRelativeUrl($url +"/results.aspx");

try{
$page.CheckOut()
$clientContext.ExecuteQuery()
Write-Host "Checking out page" -ForegroundColor Green 
}
catch{ Write-Host "Page already checked out" -ForegroundColor Yellow}
$wpm = $page.GetLimitedWebPartManager([Microsoft.SharePoint.Client.WebParts.PersonalizationScope]::Shared) 
$clientContext.Load($wpm.WebParts)
$clientContext.ExecuteQuery()
for ($i=0; $i -lt $wpm.WebParts.Count; $i++)
{
    $item = $wpm.WebParts.Item($i)
    $clientContext.Load($item.WebPart)
    $clientContext.ExecuteQuery()
    if( $item.WebPart.Title -eq "Search Results" ) {
        Write-Host "Found result web part" -ForegroundColor Green 
        break;
    }
}

$clientContext.Load($item.WebPart.Properties)
$clientContext.ExecuteQuery()
Write-Host "Turning off trimming of duplicates" -ForegroundColor Green
# Read JSON properties and convert to an object
$dataProvider = ConvertFrom-Json $item.WebPart.Properties["DataProviderJSON"]
$dataProvider.TrimDuplicates = $false
# Convert the object back to a JSON string
$item.WebPart.Properties["DataProviderJSON"] = ConvertTo-Json $dataProvider -Compress
$item.SaveWebPartChanges()
$clientContext.ExecuteQuery()
Write-Host "Checking in and publishing page" -ForegroundColor Green 
$page.CheckIn("Modified Search Core Results web part", [Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn)
$page.Publish("Modified Search Core Results web part")
$clientContext.ExecuteQuery()

Wednesday, July 10, 2013

Working with refiners in CSOM–SharePoint 2013

Topics covered in this post:
  • CSOM Search Queries
  • Working with refiners in your queries
  • ModifiedBy and EditorOWSUSER managed properties
I’m playing around using CSOM search in an App these days and find that I am using a lot more time than usual writing my code. The reason is two-fold. One: no IntelliSense, and two: not that much documentation and samples out there.

Also the quirks of setting properties in JSOM takes some learning as you have to know if the property is a collection or not. Writing C"# code, spotting collections is much more intuitive.
I’ll be using Microsoft.SharePoint.Client.Search.Query.KeywordQuery for my samples.

Wednesday, March 27, 2013

Following or favorite pages in SharePoint 2013 using JavaScript

Recently I was tasked with a project requirement that the user should be able to add pages to a favorite list. To me this sounds much like using the new following feature of SharePoint 2013 which allows you to follow documents, sites, people and tags. And the difference between a document and a page in SharePoint is more semantic than technical. Also, we don’t want the user to navigate to the pages library in order to follow the page, but do it with a link/icon on the page itself. That said, the hover panel “Follow” link does not appear by default for Pages libraries either :)

Instead of creating a custom list to hold a users favorites we decided to use the built in social following functionality using JavaScript CSOM.

So, how do you go about following a page? There are at least a couple of ways. One, write your own custom CSOM script, or two, tap into what SharePoint uses when you click “Follow” on a document or a site.
image