Forum Discussion

Deleted's avatar
Deleted
Jun 07, 2017

Invalid Package - Sharepoint Framework Extensions

I noticed today it was released the documentation about Sharepoint Framework Extensions and I wanted to give it a try.

 

I followed the steps on the tutorials, with the only difference that instead of doing a console.log or alert, I want to inject App Insights Code.

 

1. The code compiles fine, gulp serve works fine.

2. I can debug it as shown in the tutorials, without any problem, I can see the console with the messages I created on the TS file.

3. I changed the CDN path to Documents folder, yeah I know not a CDN, but I dont think this has something to do, (Oh yes I uploaded the js files to the documents library)

 

I am going to need to paste some large code here for you to get the idea:

 

package-solution.json

 
{
"solution": {
"name": "app-insights-demo-sp-fx-extension-client-side-solution",
"id": "02d35a3e-5896-4664-874f-9fe9fdfe8408",
"version": "1.0.0.0",
"features": [{
"title": "Application Extension - Deployment of custom action.",
"description": "Deploys a custom action with ClientSideComponentId association",
"id": "456da147-ced2-3036-b564-8dad5c1c2e34",
"version": "1.0.0.0",
"assets": {
"elementManifests": [
"elements.xml"
]
}
}]
},
"paths": {
"zippedPackage": "solution/app-insights-demo-sp-fx-extension.sppkg"
}
}
Elements.xml on the assets folder
 
 
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Title="SPFxApplicationCustomizer"
Location="ClientSideExtension.ApplicationCustomizer"
ClientSideComponentId="43833b44-df29-40bf-aec2-294dd435ee05">
</CustomAction>
</Elements
 
manifest.json
 
 
{
"$schema": "../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",

"id": "43833b44-df29-40bf-aec2-294dd435ee05",
"alias": "AppInsightsDemoSpFxExtensionApplication",
"componentType": "Extension",
"extensionType": "ApplicationCustomizer",
"version": "*", // The "*" signifies that the version should be taken from the package.json
"manifestVersion": 2,
"safeWithCustomScriptDisabled": true
}
and finally my extension code
 
 
import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import {
BaseApplicationCustomizer, Placeholder
} from '@microsoft/sp-application-base';
import { escape } from '@microsoft/sp-lodash-subset';

import * as strings from 'appInsightsDemoSpFxExtensionStrings';

const LOG_SOURCE: string = 'AppInsightsDemoSpFxExtensionApplicationCustomizer';

/**
* If your command set uses the ClientSideComponentProperties JSON input,
* it will be deserialized into the BaseExtension.properties object.
* You can define an interface to describe it.
*/
export interface IAppInsightsDemoSpFxExtensionApplicationCustomizerProperties {
Header: string;
}

/** A Custom Action which can be run during execution of a Client Side Application */
export default class AppInsightsDemoSpFxExtensionApplicationCustomizer
extends BaseApplicationCustomizer<IAppInsightsDemoSpFxExtensionApplicationCustomizerProperties> {

// Header reference
private _headerPlaceholder: Placeholder;

@override
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
return Promise.resolve<void>();
}

@override
public onRender(): void {
let html: string = '';
html+= `<script type="text/javascript">
"var appInsights=window.appInsights||function(config){
function i(config){t[config]=function(){var i=arguments;t.queue.push(function(){t[config].apply(t,i)})}}var t={config:config},u=document,e=window,o="script",s="AuthenticatedUserContext",h="start",c="stop",l="Track",a=l+"Event",v=l+"Page",y=u.createElement(o),r,f;y.src=config.url||"https://az416426.vo.msecnd.net/scripts/a/ai.0.js";u.getElementsByTagName(o)[0].parentNode.appendChild(y);try{t.cookie=u.cookie}catch(p){}for(t.queue=[],t.version="1.0",r=["Event","Exception","Metric","PageView","Trace","Dependency"];r.length;)i("track"+r.pop());return i("set"+s),i("clear"+s),i(h+a),i(c+a),i(h+v),i(c+v),i("flush"),config.disableExceptionTracking||(r="onerror",i("_"+r),f=e[r],e[r]=function(config,i,u,e,o){var s=f&&f(config,i,u,e,o);return s!==!0&&t["_"+r](config,i,u,e,o),s}),t
}({
instrumentationKey:"b4cf6d1c-5d38-48ce-ac4e-8a7802f2a1a0"
})
 
window.appInsights=appInsights;
appInsights.trackPageView();
</script>`;

console.log('CustomHeader.onRender()');

// Handling header place holder
if (!this._headerPlaceholder) {
this._headerPlaceholder = this.context.placeholders.tryAttach(
'PageHeader',
{
onDispose: this._onDispose
});

// The extension should not assume that the expected placeholder is available.
if (!this._headerPlaceholder) {
console.error('The expected placeholder was not found.');
return;
}

if (this.properties) {
let headerString: string = this.properties.Header;
if (!headerString) {
headerString = '(Header property was not defined.)';
}

if (this._headerPlaceholder.domElement) {
this._headerPlaceholder.domElement.innerHTML = html;
console.log('injected');
//alert('hello world');
}
}
}
}

private _onDispose(): void {
console.log('[CustomHeader._onDispose] Disposed custom header.');
}
}

 

However, when I upload the package I get in the App Catalog, the column Valid App Package = NO.

 

 

 

In case you have some time to help me, please find the attached .RAR, I guess the error is going to be something very simple.  and yes, I am working on a developer tenant.

 

 

  • Issue was in the elements.xml file, but not in encoding. More obvious than that, but still hard to catch. App catalow actually has actually "unavailable apps" link, which provides details on the possible errors and it's typically really accurate.

     

     

    If you open up the elements.xml file from the sharepoint/assets folder, you can see that the last Elements element is missing closing tag, like defined in above exception. Below is the original Elements.xml file content and you can see that we are missing final > closing. After adding that missing character there, it was all good for deployment.

     

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
        <CustomAction 
            Title="SPFxApplicationCustomizer"
            Location="ClientSideExtension.ApplicationCustomizer"
            ClientSideComponentId="43833b44-df29-40bf-aec2-294dd435ee05">
        </CustomAction>
    </Elements

    So - completely logical reason, was just hard to spot. 

  • Hi Luis - what kind of tenant do you have - do you happen to know?  The first drop will likely change a bunch, and we don't want people to be running it on production environments, so for now it requires a developer tenant (not a developer site collection, but a developer tenant).  I believe the online documentation describes how to get one, but the link is here - https://dev.office.com/devprogram

     

    Hopefully that unblocks you.

Resources