November 2007 - Posts
I am sure this is already well documented, however, its something that is really very straight forward with .NET 2.0, and not clearly written about so far on the web, so here is(hopefully) a good example:
Step 1: Embed the Resource -
Step 2: Reference the resource with the exact name and Namespace.
Step 3: Retrieve the Embedded resource
Image.ImageUrl = Page.ClientScript.GetWebResourceUrl(typeof(_Default), "[YourNamespace].Contributor.png");
It is that easy!!
In a previous post, I have discussed retrieving information from the PPS WebServices, namely, retrieving the system information, that returns information on the Applications stored within PPS. To retrieve any further data from PPS WebServices, we need to know the application ID, which is returned from the GetSystem() method.
Once you have retrieved the applications, you may notice that there are not a huge amount of WebServices methods available for use. This is because one WebServices is used to retrieve most data from PPS. Again we are going to use the MetaDataManager.asmx, WebServices, and the method we can use is the Request method, that expects an object called a PerformancePointRequest, and in turn returns a PerformancePointResponse. A PerformancePointRequest can be made to retrieve all sorts of information from PPS, and this is always returned to a PerformancePointResponse. Here is an example of code that returns Cycle instance information.
MetaDataManager.QueryFilter ppQueryFilter = new MetaDataManager.QueryFilter();
ppQueryFilter.ResultDataType = MetaDataManager.ReferenceDataType.CycleInstances;
MetaDataManager.QueryWorkflowData performancePointRequest = new MetaDataManager.QueryWorkflowData();
performancePointRequest.TargetObjectId = ApplicationID;
performancePointRequest.QueryFilter = ppQueryFilter;
MetaDataManager.PerformancePointResponse ppsResp = ppsMDM.Request(performancePointRequest);
So the PerformancePointResponse will return a standard object that can be successfully cast to a number of different objects, I have not used all objects as yet, however we have most experience with the 'WorkflowDataResponse' object. So casting the PerformancePointResponse object, to a 'WorkflowDataResponse' object, we know have a Workflow Data Object that is a set of data tables that re compressed. So.. To get the data we need to de-compress this. The following shows how I have gone about decompressing this:
First we need to get the Table Schema, that is compressed:
public static DataTable UnpackTableSchema(byte packedTableSchema)
DataTable table2 = new DataTable();
XmlSerializer dataTableSerializer = new XmlSerializer(typeof(DataTable));
if (packedTableSchema == null)
DataTable table = null;
using (MemoryStream stream = new MemoryStream(packedTableSchema))
using (GZipStream stream2 = new GZipStream(stream, CompressionMode.Decompress, true))
table = dataTableSerializer.Deserialize(stream2) as DataTable;
table2 = table;
Once we have the unpacked schema, we can unpack the data and load it against the schema:
There are quite a few methods to actually unpacking the data, so if you are interested please do not hesitate to contact me. Also, once we have finished the product, it will be available for download at http://www.adatis.co.uk. Should you like to take a look at our BETA please email us at firstname.lastname@example.org.
So.... you want to use the PerformancePoint web service so you can extend PerformancePoint, and integrate it into bespoke applications and SharePoint. We needed to create a Web part that could show a users PerformancePoint assignments in SharePoint. So, this should be simple we know that Excel uses the webservices to get all of its PerformancePoint information, so lets just tap into that and away we go... OR not!
We were after creating a WebPart that did not require any further references and was self contained. This is where life got tricky. We needed to get all the applications within Performance Point, and then get all the Assignments for each application that are related to the requesting user.
After looking through available web services, it is not clear how to retrieve the amount of data that is required to run PPS, so that was a complication. However for now lets look at how to get the applications:
We can get the whole Biz system from the Web service using this: ( where ppsMDM is the MetaDataManager web service!)
//Get the System Data
MetaDataManager.BizSystem bizSystem = ppsMDM.GetSystem(false);
This should return the whole system to a Biz system object, however, as we found the webservice attempts to cast the array of application into a dataset, and then fails to do so, meaning that we can not get the application data. After some degree of head scratching it was decided to change the Webservice Reference.cs, so the Application list was returned as an object. This enables us to then manually deserialize the XML, into our own object and get access to the entire Application object, as we should have had. It does seem that if you are willing, and able, to use the PPS Client Dll's, that you can hook straight into them to get this to work less painfully (thanks to Casper and his post here) you need to reference this (Microsoft.PerformancePoint.Planning.Client.Common) and any other dependant DLL's. This is how we have deserialize this, once creating the object ArrayOfBizApplication, and BizApplication:
foreach (XmlNode xmlNode in xmlNodes)
if (xmlNode.Name.ToLower() == "arrayofbizapplication")
System.IO.StringReader sr = new System.IO.StringReader(sb.ToString());
XmlTextReader xmlTReader = new XmlTextReader(sr);
serializer = new XmlSerializer(typeof(ArrayOfBizApplication));
arrayOfBizApplicaion = (ArrayOfBizApplication)serializer.Deserialize(xmlTReader);
Now we have the array of Applications we should be able to get the Application ID's and then the Assignements from PPS, without the need for referencing any Microsoft PPS Dll's.