Archives

Archives / 2016 / September
  • SharePoint Online CDN features announced in preview

    Tags: SharePoint Online

    Today, Mr Vesa, announced the availability of the (long awaited) CDN features for SharePoint Online. The SharePoint Online CDN features allows you to turn one or more libraries in your SharePoint tenant into a repository for assets that you want to store in a CDN for performance reasons and geo-distribution reasons.

    SPO Public CDN

    How to set things up

    I'm not going to rehash everything that is outlined in the announcement post, but rather highlight a few important things.

    To get started and turn one of your libraries into a CDN enabled library you need to install the latest SharePoint Online PowerShell cmdlets to get access to some new and updated PowerShell cmdlets. Once you have that all you need to do is first enable it on your tenant and then add libraries for cdnization:

    $creds = Get-Credential
    Connect-SPOService -Url https://contoso-admin.sharepoint.com -Credential $creds
    Set-SPOTenant -PublicCdnEnabled $true
    

    Once this is done then you choose what libraries to use as the source for your CDN. You can point directly to a library or a subfolder in a library.

    New-SPOPublicCdnOrigin -Url https://contoso.sharepoint.com/SiteAssets/
    

    When you do this you get a big and yellow warning stating that everything you add in this folder from now on will be pushed to the CDN, and that CDN is publicly available and not governed by all the nice policies we have in Office 365. So, don't put your annual report drafts in there!

    Note, it might take a few minutes until it is all ready for usage after adding or changing the origins. 15-20 minutes is not uncommon.

    You can always retrieve all your CDN origins by using the following command:

    Get-SPOPublicCdnOrigins
    

    This command will list the ID of each CDN origin as well as the origin. The ID is very important, because you need that when you construct the URL to the CDN. It's probably one or more Guids in that ID…

    How to access the files in the CDN

    To get access to the files in the CDN you need to construct a path using the ID for the CDN origin like this:

    https://publiccdn.sharepointonline.com/tenant.sharepoint.com/ID
    

    For instance

    https://publiccdn.sharepointonline.com/contoso.sharepoint.com/1544004027c884490c55638fcb53de1f5d4897c5ea7513c1c0849dd7d8f4314cbda99429
    

    Yes, it's a bit long but that's how it is.

    If you now try to access an image or script in this CDN by just typing the URL in the browser, you will get an error stating "Invalid referer". This is by design and you need to add a HTTP Header to see the image/script, the Referer header with the value of the URL of your tenant (see announcement blog). In cases where you embed the image in a page or load the script from a page, this is done automatically for you by the browser. An even easier way is to just create a page and insert a Picture from Address, and paste your CDN Url.

    Caveats

    There's a couple of caveats to the CDN as of now. One thing I had hoped was that you could use image renditions in combination with this, which would have been AWESOME. Nope, you can't. Vesa, can you add that to the todo list?

    [Update 2016-09-29] The image renditions are partly supported, you can now use width, height and cropMode (fit for instance) as query string parameters for the image. But not RenditionId - once that can be done this feature is rock solid!

    [Update 2016-09-29] CORS support has been enabled! Thanks you to the product group for fast and quick turnaround for these kind of features!

    Another quite important thing is that the CDN isn't CORS enabled. They do a check for the referer, see above, so that the request are coming from the correct tenant. But if you try to use jQuery or some other mechanism to load scripts or assets from the CDN location you get

    No 'Access-Control-Allow-Origin' header is present on the 
    requested resource. Origin 'https://tenant.sharepoint.com' is
    therefore not allowed access.
    The response had HTTP status code 406.

    I wish they added the possibility to allow CORS requests from the tenant, just as they only allow request refering from the tenant.

    Summary

    I think this feature is awesome and I have already upgraded a few tenants and customers to use this new feature for some embedded resources. Oh, did I say this is free of charge and a part of your Office 365 subscription. Free beer is good beer, despite in preview!

  • SharePoint Framework Nuggets: working with GUIDs

    Tags: SharePoint Framework

    SharePoint developers - we do like GUIDs, don't we. We all read RFC4122 both once and twice. And now with SharePoint Framework and the goal to embrace all them Macintosh and open source people - they gotta have their fair share of GUIDs.

    And to aid with that the SharePoint Framework got some really nice GUID features, although a bit unpolished as you might notice - but this is all preview bits at the time of writing.

    SharePoint Framework Nuggets - GUIDs

    The Guid class

    First of all we must have the option to create GUIDs. There might be a situation that you need to store something really, really unique - to help with the we do have the Guid class in the @microsoft/client-sp-base module. This class both allows you to create new Guids, parse Guids and validate Guids.

    This is how you import the Guid class:

    import { Guid } from '@microsoft/sp-client-base';

    Then to create a Guid, you use the code below. The newGuid method can take an optional parameter if you need to create a custom random generator. By default it generates a version 4 UUID, also known as a pseudo random UUID, which can be generated in a browser. I suggest you skip passing in custom random generators.

    var guid: Guid = Guid.newGuid();

    What if someone gives a "GUID" to you, can you trust it is a proper Guid, no you can't you need to validate it. That can be done using the isValid method, which takes a string as in input.

    if( Guid.isValid(' f0a1f189-dae4-49f5-8846-3a17429fd52') ) { alert('Valid') };

    Then we finally also have a method to parse a string potentially containing a Guid, tryParse. The method will either return a Guid object or undefined.

    var guid: Guid = Guid.tryParse('f0a1f189-dae4-49f5-8846-3a17429fd52');

    The GuidHelpers class (@internal)

    [Update 2016-09-20] - The GuidHelpers class is marked internal and will be removed in future builds of the SharePoint Framework.

    There's also another class in SharePoint Framework for Guids, the GuidHelpers class. This class lives in the @microsoft/sp-client-preview module. It has a set of similar function to generate and validate Guids, but it does not work with Guid objects, it uses strings instead. For instance the GuidHelpers.generateGuid() returns a string. Another issue is that the GuidHelpers.isValid() does not validate Guids the same way as the Guid.isValid does (issue #201 in the SPFx Repo).

    GUID validation issues

    At the moment (drop 3 of SPFx) I would stay away from the GuidHelpers class.

    As usual there's some code samples of this to be found in this Github repo: https://github.com/wictorwilen/spfx-nuggets

    Happy GUIDing!

  • SharePoint Framework Nuggets: logging like a pro

    Tags: SharePoint Framework, SharePoint

    I guess that almost every application or solution you ever built has contained some portions of a logging mechanism. And how many of you have written your own - yup, all of you! But what about the SharePoint Framework - yes, it has built-in logging!

    SharePoint Framework Nuggets - logging like a pro

    How to log in the SharePoint Framework

    Logging is a very convenient and easy way to keep track of events happening, instead of having breakpoints, or in JavaScript even worse - alerts. The SharePoint Framework (SPFx) has as all decent frameworks a built-in logging mechanism, albeit very simple, but still yet valuable. It's contained in the @microsoft/sp-client-base module and the class is called Log. To use it in your SharePoint Framework solutions you need to import it as follows:

    import {
      Log
    } from '@microsoft/sp-client-base';

    The Log class contains four static methods for logging:

    • info
    • warn
    • error
    • verbose

    The names are exactly what you expect, the info is used for information, warn for warnings, error for errors and verbose for when you just have to much on your mind and want to spit it out.

    In the SharePoint Framework implementation all logging is done to the JavaScript console and you can see the logging using the developer tools of your favorite browser. It can take some searching to find them as SPFx spits out quite a lot of logging by itself.

    All static methods have the same signature, except the error method - they take three arguments:

    • source: the source of the logging information (max 20 characters), such as method or class name
    • message: the actual message to log (max 100 characters)
    • scope: an optional service scope (more on this one later)

    The error method takes an Error object instead of the message string, otherwise they are the same.

    This is how it could be used in client side web part:

    public render(): void {
      this.context.statusRenderer.clearError(this.domElement);
      this.context.statusRenderer.displayLoadingIndicator(this.domElement, strings.Loading);
      Log.verbose('SpFxNuggets', 'Invoking render');
    
      this._webInfoProvider.getWebInfo().then((webInfo: IWebInfo) => {
        if (this.properties.fail) {
          throw new Error('Mayday');
        }
        Log.info('SpFxNuggets', 'Service OK', this.context.serviceScope);
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.context.domElement.innerHTML = `<h1>${webInfo.title}</h1>`;
    
      }).catch((err) => {
        Log.error('SpFxNuggets', err);
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.context.statusRenderer.renderError(this.domElement, err);
      });
    }
    

    In the example above I use the verbose method to log that we're in the render method. Just verbose information. I also added logging to when the service returns (the promise is fulfilled) to log information that it has returned. In that info method I use the service scope of the web part, and when using the service scope, it replaces my source with the real name (JavaScript name) of the web part. Finally I log the error in the catch method. The image below shows the console output.

    Console output

    As usual you can find all the source code in this repository: https://github.com/wictorwilen/spfx-nuggets

    Happy logging!

  • SharePoint Framework Nuggets: render error messages

    Tags: SharePoint Framework, SharePoint

    Do you write code that potentially can throw an error or an exception? Oh, you don't - but sure you use a web service or external service or something that can throw an error. Well, it is you responsibility to handle the error and make sure to inform the user in a good way that something bad happened. With that I mean, do not show just a Guid.

    With the SharePoint Framework being all client side I think it is important to have control of your client side Web Parts and make sure that you properly handle and display error messages in a consistent way. In this short post I will not go in to the JavaScript error handling details, but rather show you another nugget in the SharePoint Framework that helps you render error messages in a standardized and consistent way.

    SharePoint Framework Nuggets - Render error messages

    Render Error messages

    Just as in the last post on the loading indicator the SharePoint Framework actually has built-in functions for rendering messages in SharePointy way. In the same class (and interface) as we had the loading indicator functions we also have two methods for managing error messages, found in the context of the current client side Web Part.

    • renderError(domElement: HTMLElement, error: Error | string): void;
    • clearError(domElement: HTMLElement): void;

    The renderError  method is used to display an error message in an HTML element. It has one parameter for the error message, which can either be a string or an Error object. And the clearError removes any rendered errors in the specified DOM element.

    Here's an example on how we could use it:

    public render(): void {
      this.context.statusRenderer.clearError(this.domElement);
      this.context.statusRenderer.displayLoadingIndicator(this.domElement, strings.Loading);
    
      this._webInfoProvider.getWebInfo().then((webInfo: IWebInfo) => {
        if(this.properties.fail) {
          throw new Error('Mayday');
        }
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.context.domElement.innerHTML = `<h1>${webInfo.title}</h1>`;
    
      }).catch( (err) => {
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.context.statusRenderer.renderError(this.domElement, err);
      });
    }
    

    It's the same render method that was in the loading indicator demo but with the difference that we have added the clearError method at the beginning of the render method (once again a redundant operation since the displayLoadingIndicator will override anything inside the DOM element, but you get the point). Then I introduced a property on the Web Part that when set it will throw an error and in our catch method we use the renderError method to render the error, as shown below.

    SPFxNuggets-error

    Fully working code can be found at this repo: https://github.com/wictorwilen/spfx-nuggets

    If you carefully explored the latest drops of the SharePoint Framework (yes, this is all still beta and bits and pieces are moving around) you might notice that the BaseClientSideWebPart contains direct access to these methods (clearError and renderError). The clearError is just calling out to the statusRenderer while the renderError method first clears the loading indicator, as I do manually above, then renders the error and finally also logs the error.

    Good luck!

  • SharePoint Framework nuggets: the loading indicator

    Tags: SharePoint Framework, SharePoint

    SharePoint Framework is all about rendering stuff on the client side, avoiding the long overdue ASP.NET Web Forms technology that SharePoint (Online) is still fundamentally based on. When rendering things client side everything is done asynchronously, to avoid locking down the UI threads and having a user experience that is fluent.

    In order to give the user good feedback that things are happening in the background, you need to have some kind of visual cue that tells the user - hey I'm doing stuff now, gimme a minute. There are thousands of different ways to do this and everyone does it differently; ranging from animated gifs to "loading" texts. And everyone using different methods does not always help with the user experience - so why don't we have a common way to do this?

    We actually do have this built into the SharePoint Framework!

    SharePoint Framework Nuggets - The Loading Indicator

    The SharePoint Framework Loading Indicator

    The SharePoint Framework contains a set of nifty methods that we can use to show a loading indicator in standardized and common way.

    The SharePoint Framework contains a special interface and corresponding implementation that is called IClientSideWebPartStatusRenderer. This interface defines two methods:

    • displayLoadingIndicator(domElement: Element, loadingMessage: string): void;
    • clearLoadingIndicator(domElement: Element): void;

    The first one, displayLoadingIndicator, is used to create a loading indicator with a spinning wheel and a loading text and then replace the inner contents of a HTML element with that code. For instance, for client-side Web Parts that is loading data dynamically should use this as one of the first things in the render() method. The second one, clearLoadingIndicator, does the opposite, it removes the loading indicator.

    The IClientSideWebPartStatusRenderer is always accessible through the IWebPartContext, that is on the context object of your Web Part.

    Here's an example on how to use it:

    public render(): void {
      this.context.statusRenderer.displayLoadingIndicator(this.domElement, strings.Loading);
    
      this._webInfoProvider.getWebInfo().then((webInfo: IWebInfo) => {
        this.context.statusRenderer.clearLoadingIndicator(this.domElement);
        this.context.domElement.innerHTML = `<h1>${webInfo.title}</h1>`;
      });
    }
    

    As you can see the first things we do is to replace the whole client side Web Part with the loading indicator and a loading message. Then once our Web Part is done and have data to render, we clear out the loading indicator before rendering our stuff. In this case it is a redundant operation to clear the loading indicator, since we are replacing the whole Web Part HTML with our custom rendering. If we had a more advanced user interface we could put the loading indicator in another of our elements and then remove it.

    And this would be how it looks like in the SharePoint Workbench, when loading for 2 seconds.

    SPFxNuggets-loading

    You can get a copy of all the code at this Github repository: https://github.com/wictorwilen/spfx-nuggets

    Happy Web parting!

About Wictor...

Wictor Wilén is the Nordic Digital Workplace Lead working at Avanade. Wictor has achieved the Microsoft Certified Architect (MCA) - SharePoint 2010, Microsoft Certified Solutions Master (MCSM) - SharePoint  and Microsoft Certified Master (MCM) - SharePoint 2010 certifications. He has also been awarded Microsoft Most Valuable Professional (MVP) for seven consecutive years.

And a word from our sponsors...