maandag, oktober 14, 2013

First experiences with SharePoint 2013 item templates

Microsoft has done a great job with pushing their search technology a step further into the central arena of creating SharePoint applications:

  • Using the content by search webpart one can now show result sets across site collections whereas the content by query webpart was limited to the scope of only one site collection;
  • Using display templates in order to create customized visual representations – just by editing html templates right from your favorite html design tool.

Some caveats though that I would like to express, hoping to influence Microsoft product development:

  • Web Part configuration – the configuration of all the various content search webparts across your solution can become quite cumbersome, i.e. 1) Browse to the page, 2) Toggle Edit mode, 3) Edit the webpart, 4) Edit all the various settings of the content by search webpart, 5) Save the webpart settings, 6) Save the page. I am looking forward to a tool that will make my live easier;
  • Where is the js bundle? These display templates are automatically compiled into JavaScript files which are supplied to the user’s browser. If you have a lot of them on one page, all of these .js-files are essentially supplied separately! It would be great to have a bundler in place, that serves all JavaScript code at once;
  • Selecting the right metadata – your display template needs to know what metadata fields are available to render. SharePoint currently does not have a tool on board to help you in catching available metadata. You need to traverse from content type internal fields names into the search schema yourself to discover the metadata field names!
  • Separating html from JavaScript – Microsoft promises great separation of jobs between web designer and developer. Using display templates the web designer should be able to create presentations with their favorite html tooling. Unfortunately a display template still contains loads of JavaScript and conditional logic! We are hoping on improvements in the future;
  • Server-side rendering – with the new JavaScript based display template model, customized rendering will be taking place solely client-side. Is this good or bad? Don’t get me wrong, I really like the asynchronous processing, but I am not confortable with doing everything client-side.

woensdag, oktober 09, 2013

Troubleshooting restoring a site collection

The following applies to SharePoint 2013 RTM and potentially to SharePoint 2010, but was not tested.

Ever tried to backup and restore a site collection with PowerShell using a least privilege SPRestore account approach and bumped into some fatal errors? As a starter you should have followed the instructions that are documented on TechNet:

Restore site collections in SharePoint 2013
http://technet.microsoft.com/en-us/library/ee748655.aspx

Apparently this documention is not completely sufficient, as you bumped in some fatal errors and are seeking for help. In this blog I would like to discuss two error messages and show you how to address them.

Error 1: access denied

In PowerShell:

02/26/2013 15:38:27.95 PowerShell.exe (0x2B28) 0x2B78 SharePoint Foundation General ai1wu Medium System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)), StackTrace: at Microsoft.SharePoint.SPSite.Restore(String filename, Boolean isADMode, Boolean& readOnlyMode, Boolean& hadWriteLock) at Microsoft.SharePoint.Administration.​SPSiteCollection.Restore(String strSiteUrl, String strFilename, Boolean bOverwrite, Boolean bGradualDelete, Boolean hostHeaderAsSiteName, Boolean preserveSiteId) at Microsoft.SharePoint.PowerShell.SPCmdletRestoreSite.​InternalProcessRecord() at Microsoft.SharePoint.PowerShell.SPCmdlet.ProcessRecord() at System.Management.Automation.CommandProcessor.ProcessRecord() at System.Management.Automation.CommandProcessorBase.DoExecute() at System.Management.Automation.Internal.PipelineProcessor.Syn... 615fe450-5cc1-4608-a50d-edae5cd0d862

In ULS:

System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)), StackTrace: at Microsoft.SharePoint.SPSite.Restore(String filename, Boolean isADMode, Boolean& readOnlyMode, Boolean& hadWriteLock) at Microsoft.SharePoint.Administration.SPSiteCollection.Restore(String strSiteUrl, String strFilename, Boolean bOverwrite, Boolean bGradualDelete, Boolean hostHeaderAsSiteName, Boolean preserveSiteId) 

Solution to error 1

After some debugging we found out that the account additionally needs rights on the webapp. So ultimately one should provision an account using the following procedure:

  • Create the user SPRestore in Active Directory
  • Add the user to the local administrators group
  • Execute the Add-SPShellAdmin PowerShell command using your SPFarm account
  • Additionally execute the following PowerShell command (this is not documented within the TechNet article):
    $w = Get-SPWebApplication -identity $webapp
    $w.GrantAccessToProcessIdentity("SHAREPOINT2013\SPRestore")
    This action is equal to grant full control on the webapp via central administration. By the way, strangely, tests show that only read access is sufficient.
  • Using SQL Server Management Studio:
    Grant the SPRestore user the DB_Owner DB role of the relevant content database
    Grant SPRestore the fixed server role: securityadmin. Also strangely, although documented in the TechNet article, tests show that this latter grant is not required.

Error 2: no content database available

As you most probably already have experienced, a correctly provisioned account can still lead to the following fatal error:

In PowerShell:

Restore-SPSite : The operation that you are attempting to perform cannot be completed successfully. No content databases in the web application were available to store your site collection. The existing content databases may have reached the maximum number of site collections, or be set to read-only, or be offline, or may already contain a copy of this site collection. Create another content database for the Web application and then try the operation again.

In ULS:

System.InvalidOperationException: The operation that you are attempting to perform cannot be completed successfully. No content databases in the web application were available to store your site collection. The existing content databases may have reached the maximum number of site collections, or be set to read-only, or be offline, or may already contain a copy of this site collection. Create another content database for the Web application and then try the operation again. at Microsoft.SharePoint.Administration.SPContentDatabaseCollection​.FindBestContentDatabaseForSiteCreation(IEnumerable`1 contentDatabases, Guid siteIdToAvoid, Guid webIdToAvoid, SPContentDatabase database, SPContentDatabase databaseTheSiteWillBeDeletedFrom) at Microsoft.SharePoint.Administration.SPContentDatabaseCollection​.FindBestContentDatabaseForSiteCreation(SPSiteCreationParameters siteCreationParameters, Guid siteIdToAvoid, Guid webIdToAvoid, SPContentDatabase database, SPContentDatabase databaseTheSiteWillBeDeletedFrom) at Microsoft.SharePoint.Administration.SPSiteCollection.Restore(String strSiteUrl, String strFilename, Boolean bOverwrite, Boolean bGradualDelete, Boolean hostHeaderAsSiteName, Boolean preserveSiteId) at Microsoft.SharePoint.PowerShell.SPCmdletRestoreSite​.InternalProcessRecord() at Microsoft.SharePoint.PowerShell.SPCmdlet.ProcessRecord()

Solution to error 2

After some research (decompilation of the relevant methods within the SharePoint assemblies) it looks like SPSiteCollection.GetContentDatabase contains a bug. I created two c# snippets to simulate the innerworkings of the PowerShell command:

string SiteURL= "http://spdev/";
string BackupFile = @"c:\backup\backup.bak";
SPWebApplication webapp = SPWebApplication.Lookup(new Uri(SiteURL));
SPSiteCollection mySiteCols = webapp.Sites;
mySiteCols.Restore(SiteURL, BackupFile, true);

results in the exception.

string DatabaseServerName = "spdatabaseserver";
string ContentDatabaseName = "contentdb";
SPContentDatabase db= Support.GetContentDatabase(webapp, DatabaseServerName, ContentDatabaseName);
db.Sites.Restore(SiteURL, BackupFile, true);

does not result in the exception. This brings us to the conclusion that one should always specify database server name, and content database name. Instead of:

Restore-SPSite -Identity $SiteURL -Path $BackupFile –Force

Always use:

Restore-SPSite $SiteURL -path $BackupFile -force -databaseserver $DatabaseServerName -databasename $ContentDatabaseName

I hope this blog is of any help to all of you out there doing great SharePoint work. Please let me know if you need any further assistance.

dinsdag, juli 09, 2013

How to publish the SharePoint 2013 Task Center onto a webpart page

Have you ever wondered how you would be able to show the superb SharePoint 2013 My Site Task Center within a custom webpart page?

By inspecting the application page AllItems.aspx within the My Site site with SharePoint Designer you can find out how.

Open your webpart page in advanced mode. Register a prefix to the required namespace as follows:

And add the following webpart to your favorite webpartzone:

Et voila!

image

donderdag, mei 09, 2013

Some preparation tips for Microsoft exam 70-480 Programming in HTML5 with JavaScript and CSS3

Last week I managed to pass the Microsoft exam 70-480 Programming in HTML5 with JavaScript and CSS3 successfully. Some tips:

To prepare yourself you could do the following:

  1. Start right away with a test exam; as the exam will mostly test your basic skills, chance is big that you will already possess most of the required knowledge;
  2. Then study all the items you felt uncomfortable of thoroughly; expect a study load of around 10+ hours;
  3. Test your newly acquired knowledge with another test exam.

PLEASE NOTE: With regards to CSS3; don't waste your time with studying all the available w3c CSS3 draft specifications, as these are by far not ratified yet. Focus on the css3 features that Microsoft has included into Internet Explorer 10. Ultimately it is a Microsoft exam after all! The Internet Explorer (IE10) guide for developers can be found at the following url: http://msdn.microsoft.com/en-us/library/ie/hh673549(v=vs.85).aspx

The exam consisted out of 39 questions and among others the following was questioned:

HTML5:

  • the new semantic / functional elements: figure, figcaption, svg, canvas, aside, article, nav, progress

CSS3:

  • box model (IE10 specific implementation)
  • grid layout (IE10 specific implementation; interestingly, in the meanwhile w3c has already introduced a completely new approach)
  • text shadow (there was an error in the exam! h- and v-shadow were wrongly exchanged!)
  • relative vs absolute
  • 1 inch = 72 points

JavaScript:

  • A lot of jQuery! Among others you should really take a good look at the ajax API (cache, async, accepts, username, password properties, how to determine the mime-type of the result)
  • event handlers
  • web workers (html5)
  • messaging (html5)
  • inheritance/object-oriented programming: prototype, constructor, apply, call

dinsdag, mei 07, 2013

Apps for Outlook 2013

With their Office 2013 suite Microsoft introduces the App Store model for all major Office related applications, comparable to the App Stores for Windows 8 and Windows Phone 8:

  • Outlook
  • Word
  • Excel
  • SharePoint

This enables huge opportunities for developers to provide their custom solutions to a large customer base!

Two things I learned today with regards to apps for Outlook 2013:

1. Exchange 2013 is required

If you try to add an app for Outlook from the store, you’ll find the following instruction:

http://office.microsoft.com/en-us/store/add-apps-for-outlook-using-exchange-2013-FX102837494.aspx?ai=WA103786430

clip_image001[14]

Indeed: Exchange 2013 is required!

2. Some apps require provisioning by administrator

And, there appears to be some apps that will need to be provisioned by the administrator, for example harmon.ie:

http://office.microsoft.com/en-us/store/harmon-ie-WA103004101.aspx?queryid=b3be69de-b411-4fbe-8db8-d01a921f32eb&CTT=1

clip_image001[16]

donderdag, mei 02, 2013

SharePoint Client-Side Object Model ClientContext.Load method


Today I was struggling with my first try at some SharePoint 2013 Client Side Object Model C# code, starting with the example I found at http://www.learningsharepoint.com/2010/07/22/get-all-users-and-groups-client-object-model-sharepoint-2010/.

As all of you may know, you need to reference at least two assemblies to get this going:
  • Microsoft.SharePoint.Client.dll
  • Microsoft.SharePoint.Client.Runtime.dll
Unfortunately at that point I was still inexperienced, and I forgot to add a reference to Microsoft.SharePoint.Client.Runtime.dll.

When I tried to compile the following code:
The compiler threw the following error message:

  • 'Microsoft.SharePoint.Client.ClientContext' does not contain a definition for 'Load' and no extension method 'Load' accepting a first argument of type 'Microsoft.SharePoint.Client.ClientContext' could be found (are you missing a using directive or an assembly reference?
Luckily the compiler hinted to the possible fact that there was missing a assembly reference.

Finally, I added Microsoft.SharePoint.Client.Runtime.dll as well and the errors went away.

I found it quite confusing that I was able to use a class but not all available methods, assuming the example I took was right of course.

So I digged into the decompilation of both assemblies and this is what I found out:
  • ClientContext inherits from ClientRuntimeContext
  • ClientContext is defined in Microsoft.SharePoint.Client.dll
  • ClientRuntimeContext is defined in Microsoft.SharePoint.Client.Runtime.dll
  • ClientRuntimeContext defines the Load method:
Hopefully this piece of information is useful to some of you out there.