122013Jun

Provider-Hosted First

Microsoft wants you to use JavaScript. And if you are serious about JavaScript development, you will be out there in this JavaScript-OpenSource-world with no Microsoft to guide you. In this article i will present the concept of “Provider-Hosted-First” development. This will enable you to use modern JavaScript tools to develop your SharePoint 2013 based JavaScript Solutions.

In this article-series we will:

  1. Setup a development app ( this article )
  2. Get a grunt-server up and running ( part 2 )
  3. Develop big JavaScript Apps for SharePoint

Is this about SharePoint apps?

Well, yes and no. It is about all JavaScript Solutions you build for SharePoint 2013. But you should consider to start with a Provider-Hosted-App first. You will be able to use the power of a GRUNT server to rapidly develop your app and as soon as you are ready, you can give your code a new home. You could easily transform your app into a SharePoint-Hosted-App, Sandbox-Solution, Farm-Solution or Azure-Hosted-App.

What is this “GRUNT-Server” ?

grunt (gruntjs) is a Task-Runner based on NodeJS. Grunt will run on your local machine and once configured, it will watch your project directory to compile your less/sass files to css, minify/uglify your scripts, give you a livepreview, run unit-tests, E2E-tests, … basically, it will make you a happy happy JavaScript developer.  In part 2 we will show you how to setup a grunt server.

Make the connection

Lets see how Microsofts cross-domain goodies provide all we need to make the connection from a local grunt-server to the SharePoint 2013 context.

The Provider-Hosted App will contain no code at all. All we will need is the AppManifest.xml and two pages. The full-page and the app-part-page. In both pages we will use the SPAppIFrame (description) with the src set to our local Grunt-Server ( localhost:9000 ) . To be able to use the SP-Context, we need to include the sp.requestexecutor.js to our local JS-App. This crazy-thing (description) will create a hidden iFrame that is referencing the AppWebProxy to make the cross domain calls into SharePoint. You are able to use the REST-Api or JSOM like you are used to, only with some extra lines of code. This will work with Office365, too !

See this in actionshort screenr videocast .  After the app is deployed we only need to save changes in our project – and we get a live reload into our SharePoint site. NICE! You want that? … lets get started.

First Step: Provider-Hosted-App

jsdev
You can download the complete app here: DOWNLOAD ( if you are not able to use Visual Studio, download the .app package )

With the help of SPAppIFrame, we will have a SharePoint-Hosted App that will be some sort of Provider-Hosted App. I prefer calling it a Provider-Hosted-App, because all the code will exist on a different server – and that is the point here. We will start with a new SharePoint-Hosted App (you can start with a Provider-Hosted App and delete the xxx-web Project, too)

  • in Visual Studio 2012, crate a new SharePoint-Hosted-App. You can use your own SP-Server or use Office365 (free developer preview)
  • After the new App is created, delete the “Scripts” and “Content”-Module
  • Add a new Item “Client Web Part (Host Web) to the Project and call it “AppPart”
  • If you like a nice Icon: here . Right-click on “Images”-Module and add existing Element.

Your Solution will look like this:

solution

Next, we will setup the AppManifest.xml – doubleclick the manifest-file and

  • link to the new icon
  • open Tab “Permissions” and set all the permissions you like
  • open the code-view of the AppManifest.xml and modify the AppPrincipal:
  <AppPrincipal>
    <Internal AllowedRemoteHostUrl="http://localhost:9000"/>
  </AppPrincipal>

now, we change the default.aspx to:

<%-- The following 4 lines are ASP.NET directives needed when using SharePoint components --%>

<%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" MasterPageFile="~masterurl/default.master" Language="C#" %>

<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%-- The markup and script in the following Content element will be placed in the <head> of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
</asp:Content>

<%-- The markup in the following Content element will be placed in the TitleArea of the page --%>
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
    JSDEV - Full Page
</asp:Content>

<%-- The markup and script in the following Content element will be placed in the <body> of the page --%>
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
    <style type="text/css">
        html, body {
            overflow:hidden;
        }
        
        body {
            margin:0px;
            padding:0px;
        }
         
        iframe {
            border:0px;
            height:100%;
            width:100%;
        }

        #DeltaPlaceHolderMain {
            height: 100%; 
        }
    </style>
    
    <!-- for some reason, the StandardTokens will be translated into a wrong url ( only for SPAppIFrame ) -->
    <SharePoint:SPAppIFrame ID="SPAppIFrame1" 
        runat="server" 
        src="http://localhost:9000/#?SPHostUrl={HostUrl}&amp;SPAppWebUrl={AppWebUrl}&amp;SPLanguage={Language}&amp;SPClientTag={ClientTag}&amp;SPProductNumber={ProductNumber}" 
        frameborder="0">
    </SharePoint:SPAppIFrame>

</asp:Content>

For some reason, it is impossible to use the {{StandardTokens}}, if you want to know more, read this post

finally the AppPart.aspx:

<%@ Page language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<WebPartPages:AllowFraming ID="AllowFraming" runat="server" />

<html>
    <head>
        <title>JSDEV - App Part</title>
        <style type="text/css">
            html, body {
                overflow:hidden;
            }
        
            body {
                margin:0px;
                padding:0px;
            }
         
            iframe {
                border:0px;
                height:100%;
                width:100%;
            }
        </style>
    </head>

    <body>
        <SharePoint:SPAppIFrame ID="SPAppIFrame1" 
            runat="server" 
            src="http://localhost:9000/#?SPHostUrl={HostUrl}&amp;SPAppWebUrl={AppWebUrl}&amp;SPLanguage={Language}&amp;SPClientTag={ClientTag}&amp;SPProductNumber={ProductNumber}" 
            frameborder="0">
        </SharePoint:SPAppIFrame>
    </body>
</html>

You can now deploy this app to your SharePoint environment. During your development you may never need to deploy this app again.

What is next ?

Now, that you have our development app in place, all you need is a local grunt-server -> part 2

Leave a Reply

Your email address will not be published. Required fields are marked *

Current month ye@r day *