Apps using tenant scope permissions in a local site

If you have an autohosted SharePoint app that requests tenant scope permissions and you set the target site to a local URL you might run into a problem when debugging from Visual Studio.

The certificate is added and the app deploys fine. The user is then prompted to grant the app permission but a message notifies us that the current user does not have permission to trust the app.

Sorry, only tenant administrators can add or give access to this app

So in order to grant a user “tenant administrator” rights in a local farm complete the following:

Add the account (not via a group) to the Farm Administrators role in Central Administration

Do an IISRESET after granting the permission.

When you re-deploy the app from VS the account should now be able to click the “Trust It” button.

And you’re off to the next hurdle…

Page Layout Shenanigans

I’ve been working on a full trust SharePoint 2010 solution that uses a module to deploy some page layouts to the master page gallery and ran into an interesting scenario…

Setting the scene

I have a feature (version 1) that deploys two page layouts.

Activating the feature deployed the page layouts to the master page gallery as expected:

  • Layout1.aspx (deployed by the feature)
  • Layout2.aspx (deployed by the feature)

Then I manually uploaded an additional page layout to the master page gallery:

  • Layout1.aspx (deployed by the feature)
  • Layout2.aspx (deployed by the feature)
  • Layout3.aspx (uploaded manually)

The problem

Later I updated my feature code (version 2) to deploy an additional two page layouts called Layout3.aspx and Layout4.aspx.

The feature upgrade completed successfully and now the master page gallery contains all four page layouts as specified in version 2 of the feature:

  • Layout1.aspx (deployed by the feature)
  • Layout2.aspx (deployed by the feature)
  • Layout3.aspx (uploaded manually)
  • Layout4.aspx (deployed by the feature)

At this point the problem is that Layout3.aspx still uses the page layout that was manually uploaded (stored in the content database) and not the page layout deployed by the feature (store in the SharePoint root).

Un-ghost in the machine

My initial thought was that in order to point the list item at the page layout deployed by the feature to the SharePoint root we can un-customize the page.

Page layouts can be un-customized via the UI by going to the reset to site definition page (site actions > site settings > site actions > reset to site definition) or using code and calling the SPFile.RevertContentStream method.

Attempting to reset (un-customize) Layout3.aspx presents the following error however:

Cannot revert to the site definition version of this file. It is a custom file and is not part of the site definition.

I confirmed that Layout3.aspx had been deployed to the feature folder in the SharePoint root and it is possible to reset all the other page layouts in this way.

Digging deeper

It was time to fire up SharePoint Manager 2010 and look at the actual items in the master page gallery to determine how things work under the hood…

Looking at the page layout items in the master page gallery there are two properties of interest regarding the “customization” of pages:

The CustomizedPageStatus property is used to indicate whether an item has been customised from its definition and can be set to none, customised or uncustomized.

For Layout3.aspx this property is set to “none” whereas the working page layouts it is set to “uncustomized”.

The vti_setuppath property is set to the path of the file in the SharePoint root.

For Layout3.aspx this property was NOT set indicating that the page layout has no file in the SharePoint root.

These two properties are the reason for the exception when attempting to reset the page layout.

Now we just need to set the CustomizedPageStatus and vti_setuppath properties and we’re off to the races but as it turns out they are read-only so we need to find another way.


After the long windy road of getting here I chose to use the following technique to “repair” these properties on the Layout3.aspx page layout:

I added another upgrade (version 3 for those keeping count) to my feature:

  • Added another manifest (elementsV3.xml) to the module to deploy the same page layout with a different name (e.g. “Layout3Fix.aspx”).
  • Added a custom upgrade action that uses the SPFile.MoveTo method to replace the old Layout3.aspx with the newly deployed Layout3Fix.aspx

Upgrading the feature to version 3 will now replace the manually uploaded page layout (layout3.aspx) with the page layout from the feature. This restores the two properties discussed previously to the correct values and the page layouts now point to those deployed by the feature in the SharePoint root.

Future updates to the page layouts by solution updates will now be reflected in content pages that use these page layouts.