Sunday, May 15, 2016

401 unauthorized error in workflow when calling SharePoint 2013 based WCF web service.

SharePoint 2013 no longer allows SharePoint developers to create custom coded workflows in Visual Studio. Instead we must now create web services that we call from a workflow with the http workflow action.

when we tried to consume the web service in a workflow I got a 401 Unauthorized error.

I was rather reluctant to enable anonymous but unfortunate it turned out to be necessary to allow Workflow Manager to makes calls to my custom web service.

Before you go...

Enabling Anonymous is the first but there are two spots to control anonymous access in a web application, and you might want to consider the second one also.

For both steps: open Central administration and navigate to: Application management > Manage web applications.

To Enable Anonymous access: Click/highlight a web application row > Authentication Providers > Click 'Default'. Tick Enable anonymous access.

Your web service will now work but...

Set Policy: Click/highlight a web application row > Anonymous Policy. I discovered that if you select "Deny All - Has no access" the web service calls will still work! 

Theoretically this means anonymous access is now off again but I can still make web service calls. I do not claim to know exactly what is going on here but this seems to fit my need perfectly

How to refresh the Request Digest token

Introduction

SharePoint 2013 (and previous versions) uses a client side “token” to validate posts back to SharePoint to prevent attacks where the user might be tricked into posting data back to the server. This token is known by many names; form digest or message digest or request digest. The token is unique to a user and a site and is only valid for a (configurable) limited time.

When building Apps or customization on top of SharePoint, especially using patterns such as Single Page Applications (SPA) or using frameworks such as knockout.js it is very common that you see errors due to that the token is invalidated, which is due to that you have not reloaded the page and the token has timed out. The purpose of this article is to show you how you can refresh this form digest using JavaScript.

How to use the Request Digest token

When working with CSOM or REST you need to add the Request Digest token to your request. Well, with CSOM (JSOM) it is done for you under the hood, but when you handcraft your REST queries you need to manually add them. It usually looks something like this:

$.ajax({
    url: _spPageContextInfo.siteAbsoluteUrl + "/_api/web/,,,",
    method: "POST",
    headers: {
        "Accept": "application/json; odata=verbose",
        "X-RequestDigest": $('#__REQUESTDIGEST').val()
    },
    success: function (data) {},
    error: function (data, errorCode, errorMessage) {}
});

On line #6 we add the “X-RequestDigest” header, with the value of the hidden input field “__REQUESTDIGEST” – which is the form digest value. I will not dig deeper into this since it’s part of basically every SharePoint POST/REST sample on the interwebs.

But what happens if you’ve built a page (SPA application) where you don’t reload the page and the users work on the page for longer times than the token timeout (default 30 minutes). Then they will get exceptions like these:

HTTP/1.1 403 FORBIDDEN
{"error":{"code":"-2130575252, Microsoft.SharePoint.SPException","message":{
"lang":"en-US",
"value":"The security validation for this page is invalid and might be corrupted.
Please use your web browser's Back button to try your operation again."}}}

How to refresh the token

So how do we get a new and updated token? There are multiple ways to refresh the token, or retrieve a new and updated one. The two most common ways are to either use ye olde web services and call into the /_vti_bin/sites.asmx and use the GetUpdatedFormDigest method. To use this you have to create a SOAP message and then parse the response and retrieve the updated token. You can then either pass that new token for your subsequent requests, or even better update the hidden __REQUESTDIGEST field. The second one is to use the new REST POST endpoint /_api/contextinfo and then parse that response which can be either XML or JSON. This is how to do it the JSON way:

$.ajax({
    url: _spPageContextInfo.webAbsoluteUrl + "/_api/contextinfo",
    method: "POST",
    headers: { "Accept": "application/json; odata=verbose"},
    success: function (data) {
        $('#__REQUESTDIGEST').val(data.d.GetContextWebInformation.FormDigestValue)
    },
    error: function (data, errorCode, errorMessage) {
        alert(errorMessage)
    }
});

It’s also worth noticing that for every REST query SharePoint actually generates a new Form Digest which is sent back as a response header (X-RequestDigest), so you could always read that response header and update the form digest.

Also, if you’re not using JavaScript but instead building an app using other frameworks, platforms, languages etc – you can always use the two aforementioned methods to update the token. Well, you actually need to do it since you don’t have any hidden input field :)

How to do it the best and native way

The drawbacks with the methods above is that you have to either request a new form digest all the time to make sure that it is up to date, or catch the exception and retry your query. And as we all know this will lead to bad performance and/or cluttered JavaScript code (like we don’t have enough of that already!).

Fortunately there is a native method for refreshing the token built-in to the SharePoint JavaScript libraries. It’s a function called UpdateFormDigest(). It’s defined in INIT.js. The method takes two parameters, first of all the URL to the current site (remember the token is only valid for one site) and secondly it takes an update interval parameter. The update interval value is also already given to us, using a global constant called _spFormDigestRefreshInterval. And this is how you should use the function:

UpdateFormDigest(_spPageContextInfo.webServerRelativeUrl, _spFormDigestRefreshInterval)
As you can see, it’s very simple, only use built-in stuff and there’s no magic to it. Under the hood this method uses the /_vti_bin/sites.asmx method and it does it synchronously. This means that all you have to do is copy and paste this line into your own code just before your REST calls. The other smart thing about this method is that is uses the update interval and only updates the form digest when needed – so no extra calls.

Setting an interval of 5 minutes has it auto-refreshing and I don't have to remember to call it before my ajax.

setInterval(function() {
UpdateFormDigest(_spPageContextInfo.webServerRelativeUrl, _spFormDigestRefreshInterval);
}, 5 * 60000);

Tuesday, October 6, 2015

Get list of all features on SharePoint site.

We can use a PowerShell command to get all features on site.


Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"

Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Add-PSSnapin Microsoft.Sharepoint.Powershell

$allSiteFeatures = Get-SPFeature | Where-Object { $_.Scope -eq "Site" }
$activeFeatures = Get-SPFeature -Site "http://sitecollectionUrl"

$allSiteFeatures | ForEach-Object {
$active = $false
    foreach($feature in $activeFeatures)
    {
      if($feature.Id.ToString() -eq $_.Id.ToString())
      {
         $active = $true
      }
    }
    if(!$active)
    {
       $_.DisplayName
    }
}


Tuesday, September 15, 2015

Filtering and Sorting SharePoint List Views

Built-in URL Filtering

SharePoint’s list view controls (XsltListViewWebPart, ListViewWebPart, etc) recognize a number of parameters from the query string that can be used to filter and sort automatically a list view, without requiring any additional effort.
Filter by single value:
FilterField must be an internal field’s name and FilterValue is case insensitive.
Filter by single value and an operator:
The list of possible operators (FilterOp) is:
  • Eq: equal (default);
  • Neq: not equal;
  • Gt: greater than;
  • Lt: less than;
  • Geq: greater or equal to;
  • Leq: less or equal to;
  • BeginsWith: the start of a string;
  • Contains: part of a string.
You can add up to 10 FilterField/FilterValue/FilterOp entries, the items must match all conditions (AND operator). If you wish to filter on an additional field of a lookup field, use this syntax:
Filter by one of multiple exact values:
FilterName is also the internal name of the field and the values in FilterMultiValue are treated as case-insensitive. Separate then by ;.
Filter by one of multiple partial values:
The * character acts as a wildcard, matching anything before or after. Placing a term between * is the same as using FilterField/FilterValue with the Contains operator in FilterOp.
Filter by a taxonomy field:
If you want to filter by a managed metadata field, you can either search by the display name using FilterField and FilterValue, or you can use the ids of the terms. A little known fact is that all usages of managed metadata values – values of fields of managed metadata type – are stored in the TaxonomyHiddenList hidden list. If you want to filter by an id of a term, you need to use the following syntax (search by one of two values with FilterOp=In, values separated by commas):
Or by a single value (no need for FilterOp):
The FilterLookupId=1 is only there to tell SharePoint that it needs to search not by value (FilterValue) passed in the query string, but by term pointed by it. You can find the ids for FilterValue in the TaxonomyHiddenList list.
Sorting:
Possible values for SortDir are pretty obvious:
  • Asc: ascending (default);
  • Desc: descending.

You can only sort by a single field.


Column Names in UserInformationList

{
    //etc..
    "Title": "Sanjay Chauhan",
    "Account": "dm\\sanjayc",
    "WorkEMail": "sanjay.chauhan@domain.com",
    "MobilePhone": null,
    "AboutMe": null,
    "SIPAddress": "sanjay.chauhan@domain.com",    "IsSiteAdmin": true,
    "Deleted": false,
    "Picture": null,
    "Department": "3.14",
    "Title0": "Programmer Analyst",
    "FirstName": null,
    "LastName": null,
    "WorkPhone": null,
    "UserName": "rkauche",
    "WebSite": null,
    "AskMeAbout": "SQL Server, Windows Server, Silverlight, C#, PowerShell",
    "Office": null,
    "Id": 1,
    "ContentType": "Person",
    //etc...
}

SharePoint Web Serivces

WSS Web Services
Web Reference
Administration Service
http://<server-url:port-number>/_vti_adm/admin.asmx
Alerts Service
http://<server-url>/_vti_bin/alerts.asmx
Document Workspace Service
http://<server-url>/_vti_bin/dws.asmx
Forms Service
http://<server-url>/_vti_bin/forms.asmx
Imaging Service
http://<server-url>/_vti_bin/imaging.asmx
List Data Retrieval Service
http://<server-url>/_vti_bin/dspsts.asmx
Lists Service
http://<server-url>/_vti_bin/lists.asmx
Meetings Service
http://<server-url>/_vti_bin/meetings.asmx
Permissions Service
http://<server-url>/_vti_bin/permissions.asmx
Site Data Service
http://<server-url>/_vti_bin/sitedata.asmx
Site Service
http://<server-url>/_vti_bin/sites.asmx
Users and Groups Service
http://<server-url>/_vti_bin/usergroup.asmx
Versions Service
http://<server-url>/_vti_bin/versions.asmx
Views Service
http://<server-url>/_vti_bin/views.asmx
Web Part Pages Service
http://<server-url>/_vti_bin/webpartpages.asmx
Webs Service
http://<server-url>/_vti_bin/webs.asmx
Area Service
http://<server-url>/_vti_bin/areaservice.asmx
Query Service
http://<server-url>/_vti_bin/search.asmx
User Profile Service
http://<server-url>/_vti_bin/userprofileservice.asmx
SPS Crawl Service
http://<server-url>/_vti_bin/spscrawl.asmx
Outlook Adapter Service
http://<server-url>/_vti_bin/outlookadapter.asmx

WSS Web Services
Description
Administration Service
This Web service provides administrative capabilities like creating a new top-level site, deleting a top-level site and getting the list of available languages.
Alerts Service
Provides access to the list of active alerts and allows to delete active alerts.
Document Workspace Service
This Web service is used to manage Document Workspace sites. It allows you to create new document workspaces, delete document workspaces, create new sub-folders, delete sub-folders, and so forth.
Forms Service
Each list has forms associated which are used to display list items, create new list items, and update or delete existing list items. This Web service allows to get the collection of forms associated with a list and then get detailed information about each form.
Imaging Service
SharePoint has picture libraries that users can use to manage pictures. This Web service allows to upload pictures, download pictures, create new folders, delete folders and pictures, and the like.
List Data Retrieval Service
Allows you to run XPath like queries against a list.
Lists Service
This Web service is used to work with lists and list data. You can obtain the collection of lists, add new lists, remove lists, add new list attachments, remove attachments, and so on.
Meetings Service
This Web service is used to work with Meeting Workspaces. You can create a new Meeting workspace, remove an existing Meeting workspace, add new meetings, add new meetings using ICal files, and so forth.
Permissions Service
Sites and lists have permissions assigned to them. This Web service is used to obtain the permissions assigned to a list or site, add new permissions, and update or removing existing permissions.
Site Data Service
The Site Data Web service can be used to return meta-data about a site or list, get the collection of lists, get the attachments for a list item, get the collection of items in a list, and so on.
Site Service
This Web service can be used to return the list of site templates. When you create a new site using the Administration Web service you need to specify the site template name to use that you can obtain through this Web service.
Users and Groups Service
This Web service is used to work with users, site-groups and cross-site groups. You can add, update or remove users, site-groups, and cross-site groups. You can also add users or cross-site-groups to a site-group.
Versions Service
Document Libraries and Picture Libraries can have versioning enabled, which stores a copy of every single file version. This Web service can be used to get the list of available versions, delete versions, and also restore a file version.
Views Service
Lists have views associated that define what fields are shown, what filtering and sorting is applied, what grouping is applied, and so on. This Web service is used to work with list views. You can get the collection of views, add new views, remove views, update the Html code used to display a view, and the like.
Web Part Pages Service
Web Parts are objects that you can place on Web part pages. This Web service is used to work with Web parts and Web part pages. You can get the list of Web parts on a page, you can add or remove Web parts, and so forth.
Webs Service
This Web service is used to work with sites and sub-sites. You can get the list of list-templates, get meta-data about a sub-site, get the list of sub-sites, and so on.
Area Service
Areas are sections used in SharePoint Portal Server to group content. This Web service allows you to manage areas. You can create new areas, update areas, remove areas, get the list of sub-areas, and so forth.
Query Service
The Query Web service is used by clients to search SharePoint. You can send in complex search XML requests and get a result-set of matches.
User Profile Service
Users in SPS have user profiles that are used to target content to audiences (users). This Web service allows you to obtain user profile information. It does not allow you to create or modify user profiles.
SPS Crawl Service
This Web service is undocumented and is used by SharePoint itself for site crawling purposes.
Outlook Adapter Service
Provides the same capabilities as the Alerts Web service of WSS.

Filtering list view with query string parameters

We can filter a list using query parameters and the result will be displayed in list view, So we need a SharePoint list view for the same.
Below are the parameters we can use for filtering.

1. Create any list view you want or use a default one, for example:
http://sharepoint/Lists/MyList/AllItems.aspx

2. Call your view with the following parameters; if you already have parameters, then just add the new ones to the query string:
http://sharepoint/Lists/MyList/AllItems.aspx?FilterField1=Title&FilterValue1=ExactTitle
If here, FilterField1 value is the internally recognizable field name, not a display name or friendly name.

The FilterValue1 is the exact value to filter by, not “contains” or “begins with“, this one is assumed to be “equals“.

In this example you will receive all items, titles of which are equal to ExactTitle
So what if you want to filter by multiple values?

Here is how you do that:

http://sharepoint/Lists/MyList/AllItems.aspx?FilterName=Title&FilterMultiValue=ExactTitle1;ExactTitle2


In this example you will receive all items titles of which are equal to ExactTitle1 OR ExactTitle2

Contains:

http://YourSiteURL/Lists/Test/AllItems.aspx?FilterField1=Skills&FilterValue1=C%23&FilterOp1=Contains

What is the cost of migration to SharePoint 2016?

Below are the points to understand better how much the cost of migration to SharePoint 2016 could be for your organization: What ver...