Part I - Custom Silverlight module for Service Manager 2012 portal

Part I - Custom Silverlight module for Service Manager 2012 portal

  • Comments 8
  • Likes

In this blog we will look at how to develop a custom Silverlight module using the portal WCF service. This module will query for change requests assigned to the currently logged in portal user. Please note that this blog would be easier to understand if you have prior web development experience.

Source code for this sample application

Assumptions:

1. Familiarity with C#, Silverlight, WCF, and MVVM concepts.

2. Visual Studio 2010 is required to develop it

3. Installed Service Manager 2012 management server, and portal.

4. Understanding of SM type projections and other model based concepts.

5. Administrator level access to the portal SharePoint site and WCS web servers for deployment.

6. The sample source code was developed for SM 2012 Beta.

Steps

1. Create a new project using Silverlight application template in VS

clip_image002

2. Create a new test host for the SL application if you don’t already have one

clip_image003

3. On portal Web content Server (WCS) and extract BaseSilverlightModule.zip. This will help speed up the development of our custom module. Copy extracted folder to your solution directory.

It abstracts out the commonly needed code

1) for initializing portal WCF client proxy

2) Base viewmodel classes. E.g. for ViewModelBase can be used by all the ViewModel to connect to portal WCF

3) Data converters. E.g. DateTimeToLocalTime converter, BooleanToVisibility converter.

4) Tracing/Logging helper.

In the Silverlight application add the following references. You can find all these references by renaming any one of the SM portal Silverlight XAP to zip and then unzipping it.

E.g. MyRequestsSilverlightModule.xap

1) Microsoft.EnterpriseManagement.ServiceManager.Portal.BaseSilverlightModule.dll

2) Microsoft.EnterpriseManagement.Presentation.Core.dll (in core.zip)

3) Microsoft.EnterpriseManagement.Presentation.DataAccess.dll (in dataaccess.zip)

4) Microsoft.EnterpriseManagement.ServiceManager.Portal.BasicResources.dll (in BasicResources.zip)

5) Microsoft.EnterpriseManagement.ServiceManager.Portal.ToolkitResources.dll (in ToolkitResources.zip)

6) Microsoft.Practices.Prism.dll

7) Microsoft.Practices.Prism.UnityExtensions.dll

8) Microsoft.Practices.ServiceLocation.dll

9) Microsoft.Practices.Unity.Silverlight.dll

10) Microsoft.ServiceManager.Portal.BuildConstants.dll (provides soft references to SM mp elements and subelements).

11) System.Reactive.dll

You can find all these references by renaming any one of the SM portal Silverlight XAP to zip and then unzipping it. E.g. MyRequestsSilverlightModule.xap.

4. Delete MainPage.xaml. Create two folders for Views, and ViewModel. Build the solution and verify that it builds without any errors. At this point the Solution explorer should look like this –

clip_image005

5. Include Silverlight web client configuration file - ServiceReferences.clientConfig used to connect to the WCF service.

6. Move App.xaml and app.xaml.cs to Views folder. Class App derives from BaseApp in BaseSilverlightModule. Override CreateShell from BaseApp to load the basic resources, and set the root visual to the Shell we added in the last step.

protected override void CreateShell()
        {
            TraceManager.WriteInfo("Custom MyChange Requests CreateShell");
            ResourceManager.LoadResources(ResourcesEnum.Basic);
            this.RootVisual = new Shell();
        }

7. Add a new Silverlight page - BaseLayer.xaml to the Views folder. This is the view for the change requests. It uses one DataGrid to display the change requests and another one to display the contained activities in the selected change request.

8. Add viewmodel ChangeRequestsViewModel.cs to the ViewModel folder. It inherits from ViewModelBase in BaseSilverlightModule. ViewModelBase implements INotifyPropertyChanged and the bootstrapping code required to call into the portal WCF service.

9. Add a Silverlight usercontrol Shell.xaml to Views folder. It derives from the BaseShell in Microsoft.EnterpriseManagement.ServiceManager.Portal.BaseSilverlightModule.dll (BaseSilverlightModule). Shell.xaml binds the view BaseLayer.xaml with its viewmodel - ChangeRequestsViewModel.

<CommonSilverlightModule:BaseShell
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
           xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
           xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
           mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
           x:Name="ContentFrame" 
           xmlns:CommonSilverlightModule="clr-namespace:Microsoft.EnterpriseManagement.ServiceManager.Portal.BaseSilverlightModule;assembly=Microsoft.EnterpriseManagement.ServiceManager.Portal.BaseSilverlightModule"
           x:Class="MyChangeRequests.Views.Shell" 
           xmlns:local="clr-namespace:MyChangeRequests.ViewModel"
           Source = "/Views/BaseLayer.xaml">

    <CommonSilverlightModule:BaseShell.DataContext>
        <local:ChangeRequestsViewModel/>
    </CommonSilverlightModule:BaseShell.DataContext>
</CommonSilverlightModule:BaseShell>

10. Build the solution. Deploy MyChangeRequests.xap to the SM portal contenthost clientbin (%systemdrive%\inetpub\wwwroot\System Center Service Manager Portal\ContentHost\Clientbin). Then deploy the test page MyChangeRequestsTestPage.aspx to %systemdrive%\inetpub\wwwroot\System Center Service Manager Portal\ContentHost\Testpages.

11. Now let’s look at the how to actually query SMDB data. WCF service returns objects of type IDataObject which can be directly data bound in the Silverlight. ChangeRequestsViewModel contains two observable collections of IDataObjects – one for change requests (CR) and other for activities. We perform an asynchronous query to get the CR’s in GetChangeRequests method as seen below –

 

private void GetChangeRequests()
{
    try
    {
        TraceManager.WriteInfo("Query for change requests assigned to me");

        // display the progress bar to indicate data fetching
        this.ProgressBarVisibility = true;

        string connectionSessionTicket = null;

        // 1. Create data query command
        AsyncDataCommand<IDataObject> command = new AsyncDataCommand<IDataObject>(
                "Microsoft.EnterpriseManagement.ServiceManager.Portal.DataProviders!EnterpriseManagementObjectProjectionProvider/GetProjectionsByCriteria",
                connectionSessionTicket, new ObservableDataModel());

        // specify the type projection Id you want to query for
        command.Parameters["typeProjectionId"] = ChangeRequestsViewModel.PortalChangeRequestProjectionId;
                
        // only partial querying is supported by portal WCF service methods. 
        command.Parameters["propertyNames"] = new List<String>() { "Id", "Title", "Status", "Description", "Activity.Id", "Activity.Title", "Activity.Status" };

        // query criteria
        command.Parameters["criteria"] = ChangeRequestsViewModel.RequestsAssignedToMeCriteria;

        // 3. retrieve the query results
        command.CommandCompleted += (sender, e) =>
        {
            // hide the progress bar
            this.ProgressBarVisibility = false;

            if (e.Result == null)
            {
                this.ChangeRequestsAssignedToMe = null;
                TraceManager.WriteInfo("Number of CR assigned to me = 0");
            }
            else
            {
                this.ChangeRequestsAssignedToMe = new ObservableCollection<IDataObject>(e.Result);
                TraceManager.WriteInfo("Retrieved change requests assigned to me = " + this.ChangeRequestsAssignedToMe.Count.ToString());
            }
        };

        // 2. execute the query
        this.DataGateway.ExecuteAsync(command);
    }
    catch(Exception ex)
    {
        // hide the progress bar
        this.ProgressBarVisibility = false;

        // use TraceManager from BaseSilverlightmodule to log the exception 
        TraceManager.WriteError(ex.Message, ex.StackTrace);
    }
}
WCF service exposes create, update, and delete operations for the SM instance space. AsyncDataCommand<IDataObject> is used to do perform an asynchronous query. First you need to create the AsyncDataCommand. It needs a unique identifier for the specific service operation you want to invoke, parameters like type projection id and output columns. 

E.g. We use the operation "Microsoft.EnterpriseManagement.ServiceManager.Portal.DataProviders!EnterpriseManagementObjectProjectionProvider/GetProjectionsByCriteria" to query for all change requests and its contained activities we need to use a type projection Id, criteria to get all CR assigned to current user, and columns you would like to get back. In terms of a SQL query think of the Typeprojection Id as the join of the SQL tables, criteria as the where clause of the query and columns as the select part of the query.

Secondly execute the aysnc data command.

// 2. execute the query

this.DataGateway.ExecuteAsync(command);

Finally the retrieve the query results in the async data command completed event handler.

// 3. retrieve the query results

command.CommandCompleted += (sender, e) => {..}

Note: you can use the same operation to query over any type projection in SM. E.g. you can get all computers related to a specific change request. To do this provide the corresponding computer TypeProjection Id, criteria, and output columns.

12. Access MyChangeRequestsTestPage.aspx from the SM portal to view the change requests assigned to the current portal user.

Notes:

This test page is not a SharePoint site page so it cannot be added to the SM Sharepoint site pages collection.

Stay tuned for Part II of this blog – Creating a custom ASP.NET web part which hosts the above Silverlight module in Sharepoint.

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Fantastic bit of work!

    I was hoping this would have been included in RTM of 2012

    Looking forward to Part 2

  • Really good work!

    I have some questions about it:

    1. It is possible to use silverligt apps built with this method in Sharepoint Silverlight Web part directly?(like original apps on SCSM portal)

    2. How You are add Microsoft.Practices.Prism.dll, Microsoft.Practices.Prism.UnityExtensions.dll, Microsoft.Practices.ServiceLocation.dll like reference in Silverlight project? I have error message that there are not Silverlight assemblies.

    Thanks a lot for you work, it will be really helpful!

  • @SigmuS

    1. Yes. I am working part II of this blog explaining how to do that.

    2. You can refer to the Prism binaries built for Silverlight runtime from the sample code(ChangeRequestsSample\MyChangeRequests\portal_dependencies).

    Hope this unblocks you.  

  • Is it with this procedure also possible to change the standard Silverlight webparts and change titles etc. For example to have the Self Service Portal say anything different than need help?

  • @Giovanni -

    Check this out:

    blogs.technet.com/.../customizing-the-scsm-2012-self-service-portal-how-do-i-change-the-need-help-or-description-text.aspx

  • Thank you for the great article!

    I would like to write my own web part that submits to SCSM.  I'm looking for more information on the WCF portal service (I've never worked with WCF before).  Your line of code:

    AsyncDataCommand<IDataObject> command = new AsyncDataCommand<IDataObject>(

                   "Microsoft.EnterpriseManagement.ServiceManager.Portal.DataProviders!EnterpriseManagementObjectProjectionProvider/GetProjectionsByCriteria",

                   connectionSessionTicket, new ObservableDataModel());

    I'm trying to figure out what other "functions" besides "GetProjectionByCriteria" are available for use.  FYI, I did extensive customization of the SCSM 2010 portal so I'm familar with projections and all that jazz.  

  • Great content ...

    One question? I try to find documentation about the GetProjectionsByCriteria and any other method that the service exposes, but I cannot find any. Is there any TechNet/MSDN web that lists all the methods and its parameters?

    Thanks,

    David

  • when is the part 2 of this blog coming ?