CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Tag Archives: app

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
}

Apps can only call the OOB CSOM and REST endpoints

As a SharePoint architect or a SharePoint developer, you must have been thinking about the benefits/limitations of SharePoint apps a lot. I want to point out one of them today, which is very important: using custom webservices deployed to SharePoint inside apps. That is impossible and it is designed to be so due to the security architecture in the sharepoint app framework.

I have read much about SharePoint apps (books, whitepapers, blog posts) and stumbled over these two contradictive statements:

[…] app authenticatton is supported only for scenarios in which an app is calling to the SharePoint host environment by using client-side object model (CSOM) or the REST API. SharePoint 2013 does not support app authentication in any other endpoints beyond these. This means it is not possible to develop and deploy a set of custom web service entry points that support app authentication.

Microsoft SharePoint 2013 App Development, Microsoft Press, page 88.

This is really important to know, because it is exactly the opposite to what it is said in a Microsoft WhitePaper, where we are requested to “some outside-of-the-box thinking”:

The main reason why you would still use full-trust solutions is that a feature or API you want to use is not yet available through the REST endpoints or CSOM APIs. However, this doesn’t mean you can’t still use the server object model from an app that is on-premises. It just requires some outside-of-the-box thinking. Instead of writing a full-trust solution that completely covers the entire business scenario you are trying to satisfy, write a full-trust solution that exposes the functionality you are looking for as a REST endpoint and write an app that can use that endpoint. This will allow your solution to scale while reducing the overall exposure of full-trust code to the SharePoint environment.

Deciding between apps for SharePoint and SharePoint solutions, Microsoft. Keenan Newton.

Just to clearify, the first statement is correct. The second is unfortunately not correct. To be sure I created a web service which I deployed as a farm solution. And when I tried to invoke this webservice from my app I got 403 error and this message

The endpoint /testapp1/_vti_bin/mywebservice.svc
 is not accessible in the context of a SharePoint App.

The endpoint cannot be added within the manifest neither:
endpoint-001

Summary

While developing SharePoint apps we are restricted to the OOB CSOM and REST endpoint only.

OOB here means out-of-the-box, not outside-of-the-box.

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

jQuery mobile and SharePoint

In this post I want to explore how to build a mobile app using jQuery mobile. Recently I discovered two great blog posts about this:

  1. Building SharePoint web apps using Sencha Touch by Luc Stakenborg
  2. jQuery mobile and SharePoint by Chris Quick

In my post I’ll use their findings and share some of mine thougts. I’ll focus mostly on how to get started with jQuery mobile and SharePoint. So go ahead and create your jQuery mobile app, just drag’n’drop some controls:

Download it and yout get an “app.html” file and “my.css”. For now ignore my.css. app.html is something like that:

<!DOCTYPE html>
<html>
    <head>
<meta name="WebPartPageExpansion" content="full" />
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Hello
        </title>
        <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
    </head>
    <body>
        <div data-role="page" id="page1">
            <div data-theme="a" data-role="header">
                <h3>
                    sp + $.mobile
                </h3>
            </div>
            <div data-role="content">
                <h1>
                    Hello world
                </h1>
                <h4>
                    Sharepoint &amp; jQuery mobile
                </h4>
            </div>
            <div data-theme="a" data-role="footer">
                <h3>
                    Footer
                </h3>
            </div>
        </div>
        <script>
            //App custom javascript
        </script>
    </body>
</html>

Then your site in SharePoint designer, create a folder, call it “mobile”:

Put the app.html-file that you got from jquery.mobile.com into the “mobile”-folder and rename it to “default.aspx”:

So now it is ready!

Open your web browser and go to your site:

http://your-site/mobile

Or go to that page in your phone. But here you have to add ?mobile=0 to your url:

http://your-site/mobile/?mobile=0

aspx vs html

Using html gives you more control about the markup than aspx. Chris Quick:

Using HTML pages instead of ASPX pages allows full control of the markup produced by the solution. I did some initial experiments with data view web parts hosted on ASPX pages, but the data view web parts prefers to be wrapped in a form element. This would occasionally break the markup required for jQuery mobile. It also insured page-to-page navigation would require non-ajax navigation.

But to be able to see the html pages directly in a browser rather than getting them as files, we must change the “Browser File Handling”:
file handling

knockout: http://stackoverflow.com/questions/6089727/how-to-architecture-a-webapp-using-jquery-mobile-and-knockoutjs

SPDocumentNavigator

Want to see some real example. Check out SPDocumentNavigator (by Ben Tedder on Codeplex).

Knockout and jQuery Mobile

Let’s try the combination of knockout and jQuery Mobile. For this lab I used a very nice intro example by Thorsten Hans: SharePoint Development using HeadJS KnockoutJS and SPServices. I took it as is and put it into jQuery Mobile context:

For this example I just created a custom list, called MyContacts and added two additional columns: FirstName and WorkCity. The source code can be found on github.

Bobusos. Rövarspråk translator

BobusosI have published my old app “Rövarspråksöversättare”, an assignment on the android course. Rövarspråket is the Swedish language game. Of course Bobusos (“bus” – en:prank in Rövarspråket) is open source and can be found on Github.

Вула Чăвашла

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

Discovering SharePoint

And going crazy doing it

Bram de Jager - Coder, Speaker, Author

Office 365, SharePoint and Azure

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized Microsoft healthcare services and solution advisory firm.

Cameron Dwyer

Office 365, SharePoint, Azure, 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

DevOps, Cloud and Blockchain Consultant

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

blksthl

Mostly what I know about SharePoint - CommunicoCuspis