Last year at the Microsoft BPI Conference in Seattle over a few beers Scott Alan (a Microsoft integration technology specialist) shared with me his idea about using ASP.net 2.0 Web Parts to present BAM data. The idea was to give managers a more precise, flexible and easy to use interface into their business processes, they could essentially go to one dashboard and get a historical and current view of how various areas of their business unit or organisation were doing.
I’ve searched the blogosphere half a year later and I’m surprised no one has written about this it’s so simple to build.
The only gripe I have is that ASP.net 2.0 Web Parts cannot be deployed to SharePoint Services 2003 you’ll have to wait until the next version out later this year. You can however get to grips with how build Web Parts to show BAM data on an ASP.net 2.0 page now. (you can use Son of SmartPart see feedback below)
This post isn’t going to cover how to enable BAM it also isn’t about how to build Web Parts the basics of which are covered in these 3 tutorials:
WebParts1
WebParts2
WebParts3
Here is a simple BAM dashboard (ok I’m not a graphic designer). From the right hand side of the page the manager selects what data in which format they want to view and where on the page it should sit. Once the web part is on the page they can drag it to where ever they want or get rid of it and display another one.
All the Web Parts
How to plug into BAM
I know of three ways to access BAM data the first is obvious just grab it from the Views in the BAMPrimaryImport database, the second is by accessing the cubes in SQL Server Anaylsis Services the third is by calling the Web Services which the BAM Portal uses to access BAM data (these are installed with BAM):
http://[server]/BAM/BAMQueryService/BamQueryService.asmx
http://[server]/BAM/BAMManagementService/BamManagementService.asmx
I developed 3 simple Web User Controls to display BAM Data, as a best practice I think it’s a good idea if you develop all your web parts as Web User Controls (these will be later wrapped up as Web Parts).
Web Part
|
Usage
|
Access method
|
Orders for Redmond
|
Graph of all the orders for the city of Redmond
|
BAM Query Service GetInstanceData web method
|
Subscribe to alert
|
Allows a user to subscribe to an existing alert
|
BAM Management Service GetAlertsSummary and AddSubscription web methods
|
Orders by city
|
Report with graph displaying the number of orders per city
|
View on BAMPrimaryDataBase
|
1) Orders for Redmond web part
Controls: an ASP.net 2.0 GridView
Code: (create a web reference to the BAMQueryService)
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Principal;
public partial class OrdersForRedmond : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
//Create the instance query note that the ActivityID is always the first column returned
BamQueryService.InstanceQuery instanceQuery = new BamQueryService.InstanceQuery();
instanceQuery.SelectClauses = new string[] { "city", "product", "amount", "denied", "approved" };
//Create a filter expression and add it as a where clause
BamQueryService.ArrayOfWhereClausesFilterFilter whereClauseFilter = new BamQueryService.ArrayOfWhereClausesFilterFilter();
whereClauseFilter.Field = "City";
whereClauseFilter.Condition = "=";
whereClauseFilter.Logic = "And";
whereClauseFilter.Value = "Redmond";
instanceQuery.WhereClauses = new BamQueryService.ArrayOfWhereClausesFilterFilter[] { whereClauseFilter };
//Add credentials to call the WS (integrated security)
//Call the GetInstanceData web method and return the result
BamQueryService.BamQueryService bamQueryService = new BamQueryService.BamQueryService();
bamQueryService.Credentials = new System.Net.NetworkCredential("administrator", "pass@word1");
BamQueryService.Column[][] result = bamQueryService.GetInstanceData("SalesManager", "OrderMgmt", instanceQuery, 30);
//Fill a data table this is a quick and dirty way of creating a datasource
//probably a better way to bind a 2d array
DataTable dataTable = new DataTable("OrdersTable");
dataTable.Columns.Add(result[0][0].Name);
dataTable.Columns.Add(result[0][1].Name);
dataTable.Columns.Add(result[0][2].Name);
dataTable.Columns.Add(result[0][3].Name);
dataTable.Columns.Add(result[0][4].Name);
dataTable.Columns.Add(result[0][5].Name);
for (int i = 0; result.GetUpperBound(0) >= i; i++)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = result[i][0].Value;
dataRow[1] = result[i][1].Value;
dataRow[2] = result[i][2].Value;
dataRow[3] = result[i][3].Value;
dataRow[4] = result[i][4].Value;
dataRow[5] = result[i][5].Value;
dataTable.Rows.Add(dataRow);
}
//Fill the grid with the result
gvOrders.DataSource = dataTable;
gvOrders.DataBind();
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(this.ToString(), ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
}
}
2) Subscribe to Alert web part
Note: some alerts must exist already in the BAM Portal
Controls: An ASP.net 2.0 Drop Down List, Text Box and a Button
Code: (create a web reference to the BAMManagementService)
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Security.Principal;
public partial class SubscribeToAlert : System.Web.UI.UserControl
{
BamManagementService.BamManagementService _BamManagementService;
protected void Page_Load(object sender, EventArgs e)
{
try
{
//Fill the subscriptions combo list box
//Add credentials to call the WS (integrated security)
//Call the GetAlertsSummary web method
_BamManagementService = new BamManagementService.BamManagementService();
_BamManagementService.Credentials = new System.Net.NetworkCredential("administrator", "pass@word1");
BamManagementService.AlertSummary[] alertSummary =
_BamManagementService.GetAlertsSummary("SalesManager");
//Fill a data table this is a quick and dirty way of creating a datasource
//probably a better way to bind a 2d array
DataTable dataTable = new DataTable("AlertsTable");
dataTable.Columns.Add("Alerts");
for (int i = 0; alertSummary.GetUpperBound(0) >= i; i++)
{
DataRow dataRow = dataTable.NewRow();
dataRow[0] = alertSummary[i].Name;
dataTable.Rows.Add(dataRow);
}
//Fill the drop down list
ddlAlerts.DataSource = dataTable;
ddlAlerts.DataTextField = "Alerts";
ddlAlerts.DataValueField = "Alerts";
ddlAlerts.DataBind();
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(this.ToString(), ex.ToString(),
System.Diagnostics.EventLogEntryType.Error);
}
}
protected void btnSubscribeToAlert_Click(object sender, EventArgs e)
{
try
{
//Create a subscription
BamManagementService.Subscription subscription = new BamManagementService.Subscription();
subscription.ID = new Guid().ToString();
subscription.Type = BamManagementService.SubscriptionType.email;
subscription.UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
subscription.Address = txtEmailAddress.Text;
_BamManagementService = new BamManagementService.BamManagementService();
_BamManagementService.Credentials = new System.Net.NetworkCredential("administrator", "pass@word1");
_BamManagementService.AddSubscription("SalesManager", ddlAlerts.SelectedValue,
new BamManagementService.Subscription[] { subscription });
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry(this.ToString(), ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
}
}
}
3) Orders by City web part
- Create a dataset and connect the BAMPrimaryImport database and select the View which contains the data you’re interested in.
- Select add new item and choose report
- Drag a Chart from the toolbox onto the report
- Go to the Report menu and select Data Sources and then choose the dataset you created above
- Play with the properties of the graph until you’re happy i.e. add x y cell data
- Add a Web User Control to the project
- Add a Report Viewer control and choose the report you just created
Code: none
Now you’ve got your Web User Controls (soon to be web Parts) if you haven’t already do the 3 web part tutorials above and build your page. This is just a simple example of how you can interface with BAM & use ASP.net 2.0 web parts to empower managers.