Connector Development v4.1 User Interface Framework

The UNIFY Identity Broker Framework contains all assemblies required to develop any sub-component in the UNIFY Identity Broker Management Studio.

Extensibility Area

In MVC3 there is the concept of an Area. Briefly, an area is a sub-section of an MVC3 application, which maintains its own controllers. In the UNIFY Identity Broker Management Studio, the routing to an area is as follows:

/{Area}/{Controller}/{Action} 

and,

/{Controller}/{Action}

All plug-in user interface components are registered against the Extensibility area. As per the definition in MVC3, areas are maintained in their own subdirectory from the root, under:

/Areas/{AreaName}

as such, all components of plugin user interfaces (models, views and controllers) should be maintained under the Extensibility area through the following directory structure:

Precompiled Views

All extensibility views are packaged in .dlls. The installation process does not handle dropping the respective .cshtml files, and as such the views will need to be precompiled before they are accessible by the UNIFY Identity Broker Management Studio.

MVC3 Razor  views can be precompiled through the following steps:

  1. Download the following Visual studio extension (http://visualstudiogallery.msdn.microsoft.com/f28290ce-d987-4f91-b034-707031e10ce6)
  2. Add a reference to the Commons.Web.Mvc.PrecompiledViews  assembly maintained in the UNIFY Identity Broker Framework.
  3. In the Properties of any .cshtml file, update the Custom Tool to be MvcRazorClassGenerator

If successful, a class will be created for the view, which will be updated whenever the .cshtml file is changed.

Standard Extensions – Html.DecorateForm

The DecorateForm extension method is used to decorate a given form, to make it consistent with other forms in the UNIFY Identity Broker Management Studio. Namely - as of writing – a heading will be written above the form body, as well as a description (both of which are extracted from the SiteMap). Additionally, a back button will be added and a submit button as well.

@using (Html.DecorateForm(
    () => Html.BeginForm("CreateOrEdit", "CSVConnector", new { area = "Extensibility" }),
    "Save Settings",
    "SaveCSVConnectorForm",
    ConnectorControllerResources.SaveConnectorButtonAltText))

The above implementation would decorate the CreateOrEdit form with the all of the components mentioned above, and a submit button with the text “Save Settings”.

Standard Extensions – Html.MetaDataFor

The MetaDataFor extension method is used extensively throughout the UNIFY Identity Management Studio internally. It generates a container for a particular given property, and displays the validation messages and tool-tips for it as required.

@using (Html.MetaDataFor(model => model.FirstName, new { description = "The first name of the person" }))
{
    @Html.LabelFor(model => model.FirstName)
    @Html.TextBoxFor(model => model.FirstName)
}

The above implementation would generate a form part for the FirstName property. This form part would have a label and corresponding input text-box; When selected, the text-box would display a tool-tip with the text: 'the first name of the person’ (as defined by the description tag).

Extensible Controllers

As mentioned earlier, the plugin architecture for the UNIFY Identity Broker Management Studio works through the registration of a series of extensible controllers. Each particular sub-component (whether it is agents or connectors) has its own base extensible controller. However, each implementation achieves the same thing.

That is, they define a standard set of operations (a contract) that the management studio itself can use to interact with (In most cases this is going to be Create/Edit and Display).

Interaction with the Service

Each extensible controller implementation will expose a series of predefined properties. For example, the ExtensibleConnectorController exposes the ConnectorEngine, which is a client that manages connector components on the service side. Conversely, the ExtensibleAgentController exposes the AgentEngine. These are just sugar for the actual underlying implementation of:

return GetClient<IConnectorEngineClient>();

and,

return GetClient<IAgentEngineClient>();

If needed, any component of Identity Broker can be managed by retrieving the respective client through the GetClient method. For instance, if adapters needed to be managed for whatever reason, the adapter engine could be returned by GetClient<IAdapterEngineClient>.

Site Map (Breadcrumbs)

If you've used the Identity Broker Management Studio before, you probably will have noticed breadcrumbs on every page.

This is achieved through a series of C# [UnifySiteNode] attributes that are placed on controller actions. e.g.

[UnifySiteNode("ConnectorIndex", typeof(IdentityBrokerSiteMapResources), "HomeIndex")]
public ActionResult Index(Guid? groupId)

AShe above says that the Index action is called the ConnectorIndex site node. A resource is provided denoting where the Title and Description of the node are (default locations being [NodeName]Title and [NodeName]Description). And finally, each node has a Parent node. This all evaluates to a tree, created from the perspective of each node.

DynamicValueMapping

In some cases, the parent node of a particular page may require specific identifying information required to get to it. For example, a sub-page of the connector details will require a unique identifier of the connector to render. This information is passed up to the parent action in the form of the DynamicValueMapping attribute. This maps a value in one action to another. So for example, image the action exists on the connector controller:

[HttpGet]
[UnifySiteNode("ConnectorConnectorDetails", typeof(IdentityBrokerSiteMapResources), "ConnectorIndex", DynamicTitle = "ConnectorConnectorDetailsDynamic")]
[DynamicValueMapping("ConnectorId", "connectorId", DynamicValueMappingType.QueryString)]
public ActionResult ConnectorDetails(Guid connectorId)

Any node that uses this action as a parent must pass in a ConnectorId value, this is achieved with the DynamicValueMapping attribute. The following is a sample implementation of an child action of connector details:

[HttpGet]
[UnifySiteNode("ConnectorConnectorSchema", typeof(IdentityBrokerSiteMapResources), "ConnectorConnectorDetails")]
[DynamicValueMapping("ConnectorId", "connectorId", DynamicValueMappingType.QueryString)]
public ActionResult ConnectorSchema(Guid connectorId)

This will take the "connectorId" field in the QueryString and send it to the ConnectorDetails page when it is clicked on the sitemap. The DynamicValueMappingType enum is used to define where the source value comes from. In the case of the ConnectorSchema action, it is the QueryString as the type is HttpGet. If it were an HttpPost, it would be PostData. Finally, if the field name was id it would be RouteData.

This information can also be used to dynamically change the title of the node based on the current request, this is achieved through the DynamicTitle property. This value refers to a particular named retrieval method, so in the case of ConnectorDetails, the title key is ConnectorConnectorDetailsDynamic. This corresponds to a title retrieval method added in the constructor of the controller:

IdentityBrokerSiteMapProvider.AddTitleRetrieval(
    "ConnectorConnectorDetailsDynamic",
    (node, attribute, context, values, data, postedData, stringData) =>
    {
        string connectorId = values["ConnectorId"].ToString();
        return ServiceClient.GetConnectorDisplayName(Guid.Parse(connectorId));
    });

Is this article helpful for you?