Saturday, June 15, 2013

Create PerformancePoint Content List Programmatically

Create PerformancePoint Content List Programmatically


During one of PerformancePoint project, we need to create a custom PerformancePoint Content list to save our PerformancePoint reports.

First as usual I created the list using XML schema and everything works fine until I deployed it to staging environment.

In staging environment, if I try to create a report using Dashboard designer, I will get an error as

"You do not have permission to run a query using this report."

For saved report in the list, when try to display the report, there is an error

"The report no longer exists or you do not have permission to view it."

In the SharePoint event log, there is

06/14/2013 16:39:28.96  w3wp.exe (0x2468)                        0x182C SharePoint Foundation          Logging Correlation Data       xmnv Medium   Name=Request (GET:http://server1000:80/pps1/_layouts/ppswebparts/ReportViewPreview.aspx?SiteLocation=http%3a%2f%2fserver1000%2fpps1%2fxyz&ItemLocation=%2fpps1%2fxyz%2fLists%2fSavedReports%2f3_.000) edeeac52-ede6-4a34-b7d7-73ec6ac14012
06/14/2013 16:39:28.98  w3wp.exe (0x2468)                        0x182C SharePoint Foundation          Logging Correlation Data       xmnv Medium   Site=/pps1 edeeac52-ede6-4a34-b7d7-73ec6ac14012
06/14/2013 16:39:28.98  w3wp.exe (0x2468)                        0x182C SharePoint Foundation          Topology                       e5mc Medium   WcfSendRequest: RemoteAddress: 'http://ppsdev06:32843/3fc88cafe222497aa89ab77622ed491b/PerformancePointService.svc' Channel: 'Microsoft.PerformancePoint.Scorecards.IBIMonitoringServiceApplication' Action: 'http://www.microsoft.com/performancepoint/scorecards/IBIMonitoringServiceApplication/GetAnalyticReportView' MessageId: 'urn:uuid:6aa61912-71a0-4feb-895f-b34743b23cd4' edeeac52-ede6-4a34-b7d7-73ec6ac14012
06/14/2013 16:39:28.99  w3wp.exe (0x2468)                        0x182C PerformancePoint Service       PerformancePoint Services      ef8z Critical An exception occurred while rendering a Web control. The following diagnostic information might help to determine the cause of this problem:  Microsoft.PerformancePoint.Scorecards.BpmException: The report no longer exists or you do not have permission to view it.  PerformancePoint Services error code 20700. edeeac52-ede6-4a34-b7d7-73ec6ac14012
06/14/2013 16:39:29.02  w3wp.exe (0x2468)                        0x182C SharePoint Foundation          Topology                       e5mc Medium   WcfSendRequest: RemoteAddress: 'http://ppsdev06:32843/3fc88cafe222497aa89ab77622ed491b/PerformancePointService.svc' Channel: 'Microsoft.PerformancePoint.Scorecards.IBIMonitoringServiceApplication' Action: 'http://www.microsoft.com/performancepoint/scorecards/IBIMonitoringServiceApplication/GetSettingValue' MessageId: 'urn:uuid:a9e31515-75c1-4df5-9f43-a98aafb52ac0' edeeac52-ede6-4a34-b7d7-73ec6ac14012


In Windows Event Viewer, there  is error

"An exception occurred while rendering a Web control. The following diagnostic information might help to determine the cause of this problem: Microsoft.PerformancePoint.Scorecards.BpmException: The report no longer exists or you do not have permission to view it. PerformancePoint Services error code 20700."


The solution:

The solution is to use SharePoint object model to create the PerformancePoint Content List and don't use the XML schema.

I think the reason is that when PerformancePoint Content List is created there is some OOTB code runs and set the list to use unattended service account to call the web service. When everything runs on the same machine, it just works fine. When PerformancePoint service 'PerformancePointService.svc' runs on a different server, the list created from XML schema cannot use the proper account to call the service on a different machine.

Thursday, June 6, 2013

Master Page Url Tokens in SharePoint

Master Page Url Tokens in SharePoint
 

In SharePoint you reference master page in pages by url as


<%@ Page language="C#" MasterPageFile="...."

You can have as many master pages you want and reference them using static tokens "~site/.../master1.master" and "~sitecollection/.../master2.master"


SharePoint also supports two dynamic tokens to reference master pages.

~masterurl/default.master
~masterurl/custom.master

How to use these dynamic token can be confusing.

Basically when you start designing a portal site, you first make a decision if you want to use the static token or dynamic token. If you can use static token, you don't need worry about the dynamic tokens.

However in many situations this is not the case.

1. All OOTB application/setting pages use dynamic token. If you care about customizing the OOTB application pages, you need to use dynamic tokens.

2. All publishing portal pages which use page payout uses dynamic token. The only way to change them is to leverage dynamic tokens.

To leverage dynamic tokens, you can set SPWeb's property in code as




sysMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl, "_catalogs/masterpage/" + sysMasterUrl);
siteMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl, "_catalogs/masterpage/" + siteMasterUrl);
foreach (SPWeb site in siteCollection.AllWebs)
    {
            site.MasterUrl = sysMasterUrl;
            site.CustomMasterUrl = siteMasterUrl;
            site.Update();
    }

Dynamic tokens:
  • ~masterurl/default.master – The page references the master page file that is stored in the MasterUrl property.
  • ~masterurl/custom.master – The page references the master page file that is stored in the CustomMasterUrl property. 
 
The code will change the url of the dynmaic tokens.

The publishing portal site also provides UI to let user to change two master pages "Site Master Page" and "System Master Page". At first sight, you may think that "Site Master Page" is referring token "~masterurl/default.master " and "System Master Page" is referring token "~masterurl/custom.master".

Actually it is the opposite,

"Site Master Page" is referring token ~masterurl/custom.master
"System Master Page" is referring token "~masterurl/default.master


So in a publishing portal, if you changed the "custom.master (CustomMasterUrl)" by code or by UI, you changed all publishing pages's master page (pages under Pages library and built using page layout)

If you changed the "default.master (MasterUrl)" by code or by UI, you changed all OOTB application pages's master page.

Use Master Page on Application Page

Refer to this MSDN article 
http://msdn.microsoft.com/en-us/library/ee537530(v=office.14).aspx

SharePoint 2010 supports using DynamicMasterPageFile with the dynamic tokens

~masterurl/default.master
~masterurl/custom.master


However there are situations that you want to reference static master page from custom application page. The only way to do this is to use the old "MasterPageFile" and reference a master page in the same location as the application page.

For example, if the application is at /_layouts/myCompany/myapplication.aspx, then the master page must be at /_layouts/myCompany/mymasterpage.master

and reference it as

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="myapp1.aspx.cs" Inherits="...." MasterPageFile="mymasterpage.master" %>

If the master page is at any other location such as in the master page gallary, any attempt to try something like

MasterPageFile="~sitecollection/_catalogs/masterpage/mymasterpage.master"

or just

MasterPageFile="/_catalogs/masterpage/mymasterpage.master"

will result in errors like

System.Web.HttpException: The file '/_layouts/mycompany.Portal/~sitecollection/_catalogs/masterpage/mymasterpage.master' does not exist.    at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath)     at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)     at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile)     at System.Web.UI.BaseTemplateParser.GetReferencedType(VirtualPath virtualPath, Boolean allowNoCompile)     at System.Web.UI.PageParser.ProcessMainDirectiveAttribute(String deviceName, String name, String value, I... 9a0f3bd4-6f73-4d3d-a25d-987cec6180e1

or

System.Web.HttpException: The referenced file '/_catalogs/masterpage/mymasterpage.master' is not allowed on this page. at System.Web.UI.TemplateParser.ProcessError(String message) at System.Web.UI.BaseTemplateParser.GetReferencedType(VirtualPath virtualPath, Boolean allowNoCompile) at System.Web.UI.PageParser.ProcessMainDirectiveAttribute(String deviceName, String name, String value, IDictionary parseData) at System.Web.UI.TemplateParser.ProcessMainDirective(IDictionary mainDirective) 3146ae16-c20e-442f-9aac-90fd9cdd0597

Reference:
http://msdn.microsoft.com/en-us/library/ms476046(v=office.12).aspx

 

Tuesday, June 4, 2013

Use Site Url in SharePoint MasterPage

Use Site Url in SharePoint
 
 
There are several ways to reference site collection or site url in masterpage, layout page, application page and web parts.


1. Token: ~sitecollection ~site

These tokens only works with SharePoint server side controls. They do not work with ASP.NET control or HTML control.

2. SharePoint Server Token <% $SPUrl:~sitecollection/...%>

This token is only available for SharePoint Office Server not the SharePoint Foundation Server and it only works with a few SharePoint server controls.

If it doesn't work, you can use asp.net letral control to work around as

<script type="text/javascript" src='<asp:Literal runat="server" Text="<% $SPUrl:~Site/appBin/js/jquery.min.js %>" />'></script>

3. Emedded Code: <%=SPContext.Current.Site.ServerRelativeUrl %>

You can use the embedded code any where in application page and web parts but don't use it in master page and page layout even though they seem work, because master page and page layout can be customized. The embedded code is only allowed in the uncustomized pages.

4. SharePoint Control: <SharePoint:ProjectProperty Property="Url" runat="server"/>

You can use the value returned by this control as control attribute but this is more like an hack, but it works.

If you don't want to use it directly in attribute, you can use asp.net leteral control like this

<asp:literal runat=”server” Text=”&lt;link href=’”/>
 <SharePoint:ProjectProperty Property=”SiteUrl” runat=”server” />
 <asp:literal runat=”server” Text=”/Style Library/My Branding/MyStyles.css’ rel=’stylesheet’ type=’text/css’/&gt;”/>

 

Here is when to use which option with different controls

1. <SharePoint:ScriptLink>
The only way works for ScripLink is the token ~sitecollection

<SharePoint:ScriptLink ID="ScriptLink2" language="javascript" name="~sitecollection/_layouts/TestScript1.js" OnDemand="true" runat="server"/>

2. <Script>

Use ScriptLink to include JavaScript in SharePoint. If you have to use <Script>, then this usage will work

<script src='<SharePoint:ProjectProperty ID="ProjectProperty2" Property="Url" runat="server"/>/_layouts/TestScript4.js'></script>

3. <SharePoint:CssRegistration>

The only way works for ScripLink is the SharePoint Office Server token <% $SPUrl:~sitecollection %>

<SharePoint:CssRegistration ID="CssRegistration3" Name="<% $SPUrl:~sitecollection/_layouts/TestStyle2.css %>" After="corev4.css" runat="server"/>
 
4. <Link>

For link, try this first
 
<link rel="stylesheet" type="text/css" href="<% $SPUrl:~sitecollection/_layouts/TestStyle3.css %>">

If it doesn't work, try

<link rel="stylesheet" type="text/css" href="<SharePoint:ProjectProperty ID="ProjectProperty22" Property="SiteUrl" runat="server"/>Style%20Library/test.css"/>

5. <img>

<img src='<SharePoint:ProjectProperty ID="ProjectProperty22" Property="SiteUrl" runat="server"/>/_layouts/SiteUrlTest/blog3.png' />

Conclusion:

When you need to reference site collection url such as /sites/hr/..., try the token "~sitecollection" first. If it doesn't work, try the SharePoint Office Server token "<% $SPUrl:~sitecollection/...%>".

As last resort, try the control <SharePoint:ProjectProperty Property="Url" runat="server"/> as control attribute value or combine it usage with literal control.