CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: sharepoint apps

Onpremifying SharePoint apps

onpremify-001

We want to make an app available in SharePoint OnPrem, we want to onpremify it. Rethink SharePoint apps and provisioning SharePoint artifacts.

It has been a while since I updated my blog – Chuvash.eu. I had my vacation, I visited the sunny and green Chuvashia. Now I am back and I am looking forward to an awesome SharePoint Autumn. One of the first things I had to deal with in this SharePoint Autumn was Onpremifying of a SharePoint Online App. We have an app that has gained popularity and we want to make it available for SharePoint OnPrem. There is no such word Onpremify (yet?), I know, it is a Swenglish happy word making (onpremifiera), but I like the word “onpremify” a lot.

There is still uncertainty around the purpose of SharePoint apps. One app type, though, has been used a lot in our company: an app that provisions SharePoint Artifacts – that creates SharePoint Applications. What I mean by SharePoint Applications can be read in my blog post:

The successful app type creates SharePoint Applications – by provisioning needed SharePoint artifacts (Fields, Content Types, Lists, Page Layouts, Styles, Scripts, Web Parts, Pages…). Often it is a one time job: When the SharePoint application is provisioined, it is finished.

onpremify-002

When you’re about to onpremify such an app, you have three main choices:

  1. Install app in OnPrem. Requires the App Infrastructure in place and a separate build of the app (15.0.0.0 version)
  2. Make a parallel version of the app using a farm solution (not good at all)
  3. Invoke the provisioning code from a console app (I recommend this one)

The choice 1 might seem obvious, but not all companies have a functioning app infrastructure (a dedicated server for Provider Hosted apps, S2S Trust and Governance around it). The choice 2 splits your app into two variants and makes it hard to maintain.

On the other hand, the choice 3 might seem crazy, when you hear it for the first time. A Console App? But give it time, think about it. The idea comes from the awesome SharePoint Provisioning Library SPMeta2, where the Model (SharePoint Artifacts) and Executing are separated. Your model for Fields, Content Types, and Lists and so on, is an agnostic code based definition that can be used for SSOM and CSOM, for SharePoint 2013, SharePoint Online, SharePoint 2016 and SharePoint 2010. SPMeta2 eliminates the need for XML and wsp packages.

So my recommended approach for onpremifying SharePoint apps where the main goal is to provision SharePoint Applications is to move the provisioning code into a separate VS Project. The SharePoint App Project (mainly AppManifest.xml) remains the same, The App Web Project is made to a “stupid” interface that invokes the Provisioning Library. We also create a new interface – a Console App. You can replace the console app with a Windows Application, a Web Application, PowerShell Script, An admin page in Central Admin – whatever suits you. The Console app can be used not only in OnPrem, but also in SharePoint Online.

SPMeta2 vs. PnP vs. Own Framework

Every developer with Self-Respect uses a framework for provisioning SharePoint artifacts. It might be some own utilities or preferably public framework, because you don’t want to repeat yourself, especially in SharePoint. When SPMeta2 and PnP are available it is not smart to reinvent the wheel. I usually recommend to use one of them. I personally prefer SPMeta2 because… mainly because it is more complete and consistent. Read more about SPMeta2 vs. PnP comparison.

Advertisements

What about the SharePoint app domain?

This is an open question about the domains for SharePoint apps. On Technet: Configure an environment for apps for SharePoint (SharePoint 2013) we can read the following:

You must configure a new name in Domain Name Services (DNS) to host the apps. To help improve security, the domain name should not be a subdomain of the domain that hosts the SharePoint sites. For example, if the SharePoint sites are at Contoso.com, consider ContosoApps.com instead of App.Contoso.com as the domain name.

Does it apply to SharePoint Online? Well, apparently not 🙂 So why should we do it on premises?

subdomain

As we all know, sharepoint.com is used for our Office 365 tenancies and for apps.

PowerShell: Get version and ProductId from an .app package

In my project I deploy some apps directly through the ObjectModel directly with PowerShell. The apps are built with TFS

I have a script that installs or updates apps if there is a new version of the app. Previously I used Import-SPAppPackage to compare the version and productid with an existing app instance, but often I get this error:

The provided App differs from another App with the same version and product ID.

Here you have the issue. Now the solution is to read the AppManifest.xml. But first the .app package has to be extracted like a usual zip file. This is the powershell function for that:

function Get-SPAppPackageMetadata {
  <#
  .SYNOPSIS
    Gets the version and productid of an app package
  .DESCRIPTION
    This function extracts the AppManifest.xml from the app and gets the Version and the ProductId
  .EXAMPLE
    Get-SPAppPackageMetadata- AppPackagePath "C:\folder\app.publish\1.0.0.1\App1.app"
  .PARAMETER AppPackagePath
    The path to the new version of the app
  .Notes
        Name: Get-SPAppPackageVersion
        Author: Anatoly Mironov
        Last Edit: 2013-12-05
        Keywords: SPApp, SPAppInstance
  .Link
        http://chuvash.eu
  #>
    [CmdLetBinding()]
    param([Parameter(Mandatory=$true)][string]$AppPackagePath)

    $shell = new-object -com shell.application
    $item = get-item $AppPackagePath
    $zipFilePath = $item.FullName + ".zip"
    
    $directory = $item.Directory.FullName
    Copy-Item $item $zipFilePath
    $manifest = @{ "Name" = "AppManifest.xml" }
    $manifest.Path = Join-Path $directory $manifest.Name
    $manifest.File = $shell.NameSpace($zipFilePath).Items() | ? { $_.Name -eq $manifest.Name }
    $shell.Namespace($directory).CopyHere($manifest.File)
    $manifest.Xml = [xml](get-content $manifest.Path)
    $metadata = @{
        "VersionString" = $manifest.Xml.App.Version
        "ProductId" = $manifest.Xml.App.ProductID
    }


    Remove-Item $zipFilePath
    Remove-Item $manifest.Path

    return $metadata
}

Convert any web app to a SharePoint app

convert-app-001

Have you noticed that you can right-click a web application project in Visual Studio and convert it to a provider hosted app? Well why not? Basically your own website and a SharePoint manifest is all what you need for a provider hosted app.

convert-app-002

This discovery today made me think about all legacy web apps out there that can be converted to SharePoint apps.  Traditionally we had to add plain links to external applications or embed them into an IFrame by hardcoding it in an .aspx page or a Page Viewer WebPart.

A web application that should be converted to a SharePoint app can be any web app, not only asp.net web site.

For a year ago, I had a little nodejs project to try out mongodb and knockout.js: Anvaska which I published as a heroku app:

Now I want to try to convert this to a SharePoint app. I am satisfied when:

  1. A full page app is rendering Anvaska
  2. The SharePoint app renders the chrome control (suiteBar) if the app runs within a SharePoint context
1. A full page app

To create a link to Anvaska is simple. I only have to add the link in the manifest file:

Anvaska
http://anvaska.herokuapp.com/?StandardTokens

convert-app-003

But when I click on the app, there is a problem:

convert-app-004

A “POST” to this site? Why? The reason is the application page called appredirect which makes a “POST” call:

  • /_layouts/15/appredirect.aspx?instance_id={F9049494-42D0-4077-9F34-88A35B7271B9}

In the hive you can see why. The redirect page uses a form and POST method:

convert-app-005

<form id="frmRedirect" action="<%= SPHttpUtility.HtmlEncode(SPHttpUtility.UrlPathEncode(RedirectLaunchUrl, false)) %>" method="post">
 <input type="hidden" name="SPAppToken" value="<%= SPHttpUtility.HtmlEncode(AppToken) %>" />
 <input type="hidden" name="SPSiteUrl" value="<%= SPHttpUtility.HtmlEncode(Web.Url) %>" />
 <input type="hidden" name="SPSiteTitle" value="<%= SPHttpUtility.HtmlEncode(Web.Title) %>" />
 <input type="hidden" name="SPSiteLogoUrl" value="<%= SPHttpUtility.HtmlEncode(Web.SiteLogoUrl) %>" />
 <input type="hidden" name="SPSiteLanguage" value="<%= SPHttpUtility.HtmlEncode(Web.UICulture.Name) %>" />
 <input type="hidden" name="SPSiteCulture" value="<%= SPHttpUtility.HtmlEncode(System.Threading.Thread.CurrentThread.CurrentUICulture.Name) %>" />
 <input type="hidden" name="SPRedirectMessage" value="<%= SPHttpUtility.HtmlEncode(RedirectMessage) %>" />
 <input type="hidden" name="SPErrorCorrelationId" value="<%= SPHttpUtility.HtmlEncode(ErrorCorrelationId) %>" />
 <input type="hidden" name="SPErrorInfo" value="<%= SPHttpUtility.HtmlEncode(ErrorInfo) %>" />
</form>

Just of curiosity, I tried to change method=”post” to method=”get” and the app worked. Of course you never should change any SharePoint built-in controls or pages. So there must be another solution. The asp.net web sites are okay with the external POST calls, but pages like wordpress, *.herokuapp.com don’t allow external POST redirects.

The anvaska application uses nodejs, expressjs. To solve this issue in this particular application I can do a redirect in express js:

var express = require("express");
var app = express();
app.post('/', function(req, res){
    res.redirect(req.url);
});
app.listen(process.env.PORT || "8080");

SharePoint Matryoshka

Russian Nested Doll: Matryoshka

To overcome this issue with the POST verb, a nested iframe can be used. Recently, I wrote a post about “Provider Hosted First Approach” where I presented the original idea of Thomas Deutsch. The implementation is an SPAppIframe which covers the whole html body. In an app part it would cause a nested iframe. But it would work.

<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>
2. SharePoint Chrome Control (suiteBar)

To add a SharePoint Chrome Control is easy. Just follow this MSDN article:

Add a javascript file to your project: spapp-chrome.js and refer to it from your website page. That’s it. Here is the screenshot:

convert-app-006

Summary

With a little effort, any legacy web application can be converted into a SharePoint app and be part of a bigger intranet, can be added by users in the sites where it is meaningful rather than just adding links to all existing external applications. These SharePoint apps could even interact with SharePoint and even have appwebs if it makes sense. What do you think? Let me know.

SharePoint Apps: “Provider Hosted First” Approach

Recently I had an exciting mail conversation with Thomas Deutsch. He came up with an idea how to fasten the development of apps. This smart approach is called “Provider Hosted First”. See Thomas’ original blog post. Here are some highlights:

What you actually do is a local website which runs in grunt server:

localhost:9000

Then a SharePoint-hosted app is created with an SPAppIframe that refers to that local app site. Genious!!!

Some key features of this approach:

  • This local app contains a livereload script. Your sharepoint app is updated every time you save your css, js, html file in your IDE
  • Grunt minifies, bundles your assets
  • Grunt runs your tests automatically when your content is modified
  • The SharePoint app can be on Premises, on Office 365, wherever you want it.

Video

See the video how it looks like to develop using this approach

See the video how it looks like to develop using this approach

Very nice intro to sp app logging

Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager talking Office 365, SharePoint and Azure

My view and thoughts on Productivity and more.

My programming life

and everything in between

SharePoint Development Lab by @avishnyakov

It is a good place to share some SharePoint stories and development practices.

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized healthcare services and solution advisory firm.

Mai Omar Desouki - Avid SharePointer

Egyptian & Vodafoner - Senior SharePoint Consultant

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points!!

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

Aryan Nava

BigData and Blockchain expert in Toronto

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint