Wednesday, March 3, 2010

Programmatic deployment of Workflow-controlled EPT

In the previous article we’ve shown the way how to programmatically create a Workflow Association. Here you can find the description of programmatic creation of Workflow-controlled EPT.

When you have deployed the Workflow Association, it is possible to create an EPT programmatically. This action can be performed in FeatureActivated overridden SharePoint feature method as well. The Workflow PSI web service should be used for this purpose. Here is the code sample:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    var site = (SPSite)properties.Feature.Parent;
    var pwaWorkflow = new Workflow();
    pwaWorkflow.Url = string.format("{0}/_vti_bin/psi/Workflow.asmx"),site.Url);
    pwaWorkflow.Credentials = System.Net.CredentialCache.DefaultCredentials;

    using (var dsProjectType = pwaWorkflow.ReadEnterpriseProjectType(Guid.Empty))
    {
        WorkflowDataSet.EnterpriseProjectTypeRow row = 
dsProjectType.EnterpriseProjectType.NewEnterpriseProjectTypeRow();

        //Fill EPT Row
        ...
        var wfAssociationName = "[Your_WF_Association_Name]";
        row.WORKFLOW_ASSOCIATION_UID = GetWorkflowUidByName(wfAssociationName);
                row.WORKFLOW_ASSOCIATION_NAME = wfAssociationName;
        ...

        dsProjectType
            .EnterpriseProjectType
            .AddEnterpriseProjectTypeRow(row);

        pwaWorkflow.CreateEnterpriseProjectType(dsProjectType);
    }
}

private Guid GetWorkflowUidByName(Workflow pwaWorkflow, string workflowName)
{
    using (var dsWorkFlow = pwaWorkflow.ReadWorkflows())
    {
        return dsWorkFlow.WorkflowAssociation.Rows
            .Cast<WorkflowDataSet.WorkflowAssociationRow>()
            .First(row =>
                   row.WORKFLOW_ASSOCIATION_NAME == workflowName)
            .WORKFLOW_ASSOCIATION_UID;
    }
}

As it is shown in the code, you should use the ReadWorkflows method of Workflow.asmx web service to reach the ID of Workflow Association. Then you should set the WORKFLOW_ASSOCIATION_UID and WORKFLOW_ASSOCIATION_NAME properties of the EPT row. All other EPT properties should be filled out as usual.

IMPORTANT: If you have your EPT Workflow-controlled, it should have no PDPs attached. If you have to make existent EPT Workflow-controlled, you should first remove PDPs associations for this EPT, and then set WORKFLOW_ASSOCIATION_UID / WORKFLOW_ASSOCIATION_NAME properties.

3 comments:

  1. I get the follow error:
    ProjectServerError(s) LastError=EnterpriseProjectTypeCreatePDPIsRequired

    In http://msdn.microsoft.com/en-us/library/ms508961.aspx we read:

    "An enterprise project template (EPT) for a workflow requires an associated Create type project detail page (PDP) to create a project using the EPT. This error occurs when the PDP is not included in the EPT definition. Other PDP types are Normal for editing a project and Workflow Status for showing details of a project related to workflow."

    How I associate the PDP to my Workflow-controlled EPT programmatically?

    I appreciate any help.

    ReplyDelete
  2. You should add a row to EnterpriseProjectTypePDPs table of WorkflowDataSet dataset. There you should set IS_CREATE_PDP to true.
    PS. Try our FluentPS project - you can both use binaries and chech the source code and find what you are looking for.

    ReplyDelete