none
Ho to access project site through workflow code? RRS feed

  • Question

  • Hello!

    In my code of workflow, I need to access the project site and change some permissions on lists during the workflow.

    How can I access the project site from within the workflow? Can anyone help?

     Tanks!

    Eduardo

    Thursday, January 20, 2011 3:51 PM

Answers

  • Hello Jim,

    While I was waiting for your reply, I decided to try on the other hand and found another solution, see just how did:

     // Class property for the workflow properties.
            public SPWorkflowActivationProperties workflowProperties
            { getset; }

            // Class property for the workflow context.
            public Microsoft.SharePoint.WorkflowActions.WorkflowContext wfContext
            { getset; }
     private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
            {
                wfContext.Initialize(workflowProperties);


            }
    private void ChangePermissions(object sender, EventArgs e)
            {

                var urlTeste = wfContext.CurrentWebUrl;

                var siteUrl = wfContext.CurrentWebUrl;

                SPSite site = new SPSite(siteUrl);

                //ProjectName is a vector which is filled with the action of readProjectProperty, this is in the workflow toobox
                SPWeb web = site.AllWebs[projectName[0]];

                web.AllowUnsafeUpdates = true;

                SPList biblioteca = web.Lists["Planejamento"];

                biblioteca.BreakRoleInheritance(false);

                SPRoleDefinitionCollection webroledefinitions = web.RoleDefinitions;

                SPGroup group = web.SiteGroups["Designers"];


                SPRoleAssignment roleassignment = new SPRoleAssignment(group);
                // roleassignment.RoleDefinitionBindings.RemoveAll();

                biblioteca.ResetRoleInheritance();
                biblioteca.Update();


                biblioteca.BreakRoleInheritance(false);
                biblioteca.Update();

                roleassignment.RoleDefinitionBindings.Add(web.RoleDefinitions.GetByType(SPRoleType.Reader));

                biblioteca.RoleAssignments.Add(roleassignment);
                biblioteca.Update();

                web.AllowUnsafeUpdates = false;
            }

     

    This code worked, but I still would like your answer to the question I asked earlier.

    Thank you

    Eduardo
    • Marked as answer by Jim Corbin Monday, January 24, 2011 5:15 AM
    Friday, January 21, 2011 6:13 PM

All replies

  • Hi Eduardo,

    You can get the WPROJ_STS_SUBWEB_NAME and WSTS_SERVER_UID fields in the ProjectDataSet.ProjectRow by using the Project.ReadProjectEntities method. The workflow has built-in access and enhanceed permissions for the Project service through the Microsoft.Office.Project.Server.WebServiceProxy namespace.

    Alternately, you would be bound by the workflow user's permissions (I think -- haven't tried this), if you get a reference to the Project service and programmatically configure the WCF endpoint (not by app.config). The SDK has examples of programmatically configuring the Project service, such as the Creating a Page for a Modal Dialog Box section in Walkthrough: Customizing the PWA Ribbon and Accessing the JS Grid.

    --Jim


    Jim Corbin [MSFT]
    Thursday, January 20, 2011 4:48 PM
  • Hello Jim,

    Is there any example of the first implementation that you recommended? I'm a little confused on how and where to instantiate these classes and call their methods.

    Tanks,


    Eduardo
    Thursday, January 20, 2011 5:47 PM
  • No example that I could find. In your workflow solution, set references to Microsoft.Office.Project.Server.Library and Microsoft.Office.Project.Schema (that's in C:\Windows\assembly\GAC_MSIL\...). The WebServiceProxy namespace is in the Microsoft.Office.Project.Server.Workflow.dll assembly. Add using statements, such as:

    using WfPsiProxy = Microsoft.Office.Project.Server.WebServiceProxy;
    
    using PsSchema = Microsoft.Office.Project.Server.Schema;
    
    using PsLib = Microsoft.Office.Project.Server.Library;
    
    

    In the appropriate method in your workflow, add code such as:

      WfPsiProxy.Project proj = new WfPsiProxy.Project();
    
      // Get the list of projects in the Published DB.
      PsSchema.ProjectDataSet projDs = proj.ReadProjectStatus(
        Guid.Empty, PsLib.DataStoreEnum.PublishedStore, string.Empty, 
        (int)PsLib.Project.ProjectType.Project);
    
      // Iterate through projDs to find the PROJ_UID for the name of the project.
      // The following line assumes the first row in the ProjectDataSet.ProjectDataTable is the correct row.
      Guid projUid = projDs.Project[0].PROJ_UID;
    
      const int PROJECT_ENTITY_TYPE_PROJECT = 1;
    
      projDs = proj.ReadProjectEntities(projUid, PROJECT_ENTITY_TYPE_PROJECT, 
        PsLib.DataStoreEnum.PublishedStore);
    
    
      string projectSiteName = string.Empty;
          
      if (! projDs.Project[0].IsWPROJ_STS_SUBWEB_NAMENull())
        projectSiteName = projDs.Project[0].WPROJ_STS_SUBWEB_NAME;
    

    Also get WSTS_SERVER_UID if you need it. Once you have the project site name, use the SharePoint API to change permissions on lists.

    --Jim


    Jim Corbin [MSFT]
    • Marked as answer by Eduardo Araújo Friday, January 21, 2011 1:02 AM
    • Unmarked as answer by Jim Corbin Monday, January 24, 2011 5:12 AM
    Thursday, January 20, 2011 9:16 PM
  • Hello Jim,

    Thanks a lot!

    You saved my neck.
    []'s
    Eduardo

     

    Friday, January 21, 2011 1:06 AM
  • I'm not able to instantiate an object of this class WfPsiProxy.Project proj = new WfPsiProxy.Project() because it does not have a constructor.

    How can I solve this?

    Thank you

    Eduardo
    Friday, January 21, 2011 3:28 PM
  • Hello Jim,

    While I was waiting for your reply, I decided to try on the other hand and found another solution, see just how did:

     // Class property for the workflow properties.
            public SPWorkflowActivationProperties workflowProperties
            { getset; }

            // Class property for the workflow context.
            public Microsoft.SharePoint.WorkflowActions.WorkflowContext wfContext
            { getset; }
     private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
            {
                wfContext.Initialize(workflowProperties);


            }
    private void ChangePermissions(object sender, EventArgs e)
            {

                var urlTeste = wfContext.CurrentWebUrl;

                var siteUrl = wfContext.CurrentWebUrl;

                SPSite site = new SPSite(siteUrl);

                //ProjectName is a vector which is filled with the action of readProjectProperty, this is in the workflow toobox
                SPWeb web = site.AllWebs[projectName[0]];

                web.AllowUnsafeUpdates = true;

                SPList biblioteca = web.Lists["Planejamento"];

                biblioteca.BreakRoleInheritance(false);

                SPRoleDefinitionCollection webroledefinitions = web.RoleDefinitions;

                SPGroup group = web.SiteGroups["Designers"];


                SPRoleAssignment roleassignment = new SPRoleAssignment(group);
                // roleassignment.RoleDefinitionBindings.RemoveAll();

                biblioteca.ResetRoleInheritance();
                biblioteca.Update();


                biblioteca.BreakRoleInheritance(false);
                biblioteca.Update();

                roleassignment.RoleDefinitionBindings.Add(web.RoleDefinitions.GetByType(SPRoleType.Reader));

                biblioteca.RoleAssignments.Add(roleassignment);
                biblioteca.Update();

                web.AllowUnsafeUpdates = false;
            }

     

    This code worked, but I still would like your answer to the question I asked earlier.

    Thank you

    Eduardo
    • Marked as answer by Jim Corbin Monday, January 24, 2011 5:15 AM
    Friday, January 21, 2011 6:13 PM
  • Sorry, I was mistaken about using the WebServiceProxy. Glad you found an answer.

    --Jim


    Jim Corbin [MSFT]
    Monday, January 24, 2011 5:15 AM
  • Hello Jim,

    I'm having the same problem as Eduardo when trying to instantiate the proxy class. In the line

    WfPsiProxy.Project proj = new WfPsiProxy.Project();
    

    I get the following error:

    "The type 'Microsoft.Office.Project.Server.WebServiceProxy.Project' has no constructors defined"

    Do you know what may cause this? I've been trying to fix this for a while, and couldn't find anything suitable.

    Thanks in advance!

     

    Thursday, May 19, 2011 11:34 AM
  • Sorry, the answer above, and the SDK topic Microsoft.Office.Project.Server.WebServiceProxy Namespace, is incorrect. That SDK topic will be changed in the next update (early July).

    Classes in the WebServiceProxy namespace are used only internally. They are compiled as PSI proxies into the PWA.dll and Workflow.dll assemblies. These proxies are used to internally call the PSI from PWA or from a workflow that uses the built-in Project Server workflow activities. The WebServiceProxy classes are not meant to be directly used -- as you found out.

    To call the PSI from a workflow, you need to create a custom Project Server activity. There is a good example in the CustomWorkflow solution that's in the SDK download.

    --Jim


    Jim Corbin [MSFT]
    Thursday, May 19, 2011 6:37 PM