none
Update multiple project properties RRS feed

  • Question

  • Hi, I'm trying to use the updateProjectProperty activity to update custom fields from within my workflow. I've got a sequence to force a check-in of the project, update a property and then publish the project. The problem arises when I try to use the updateProjectProperty activity multiple times in the sequence. The first update completes, but the second update does not complete with status saying the project is checked out. Do I need to force another check-in before each use of updateProjectProperty?
    Thursday, August 25, 2011 5:47 PM

Answers

  • Yes, try checking it back in.
    Jack Dahlgren blogs at:
    Project and Retrovention
    and rarely Twitter
    • Marked as answer by YaleM4208 Monday, August 29, 2011 1:37 PM
    Friday, August 26, 2011 1:49 PM
    Moderator
  • Thanks, I actually ended up updating the fields through the PSI and ProjectDataSet. I feel it allows a little tighter control of the check-in/check-out/update/publish process. I created a nice helper method to update a single custom field given the CF's name and projectDataSet.
    • Marked as answer by YaleM4208 Monday, August 29, 2011 1:37 PM
    Monday, August 29, 2011 1:36 PM

All replies

  • Yes, try checking it back in.
    Jack Dahlgren blogs at:
    Project and Retrovention
    and rarely Twitter
    • Marked as answer by YaleM4208 Monday, August 29, 2011 1:37 PM
    Friday, August 26, 2011 1:49 PM
    Moderator
  • Thanks, I actually ended up updating the fields through the PSI and ProjectDataSet. I feel it allows a little tighter control of the check-in/check-out/update/publish process. I created a nice helper method to update a single custom field given the CF's name and projectDataSet.
    • Marked as answer by YaleM4208 Monday, August 29, 2011 1:37 PM
    Monday, August 29, 2011 1:36 PM
  • Hi YaleMFTL

    I've been having some issues in attempting to do this.

    My code fails when calling the QueueUpdateProject method after successfully checking out the current workflow project.

    Can you post some sample code of how you did this?

    Thanks for your help.

    Kevin

     

    Wednesday, September 14, 2011 2:49 PM
  • Kevin,

    What type of error are you getting when your code fails? Did you get this working yet?

     

    By no means am I an expert, so take the code samples with a grain of salt. This is just what I was able to get working under our tight time constraint, it could probably be cleaned up.

            private ProjectClient InitializeProjectClient()
            {
                // Create a basic binding.
                BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
    
                binding.Name = "basicHttpConf";
                binding.SendTimeout = TimeSpan.MaxValue;
                binding.MaxReceivedMessageSize = MAXSIZE;
                binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
                binding.MessageEncoding = WSMessageEncoding.Text;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    
                // The endpoint address is the ProjectServer.svc router for all public PSI calls.
                EndpointAddress address = new EndpointAddress(workflowProperties.WebUrl + WorkflowStrings.SVC_ROUTER);
    
                ProjectClient projectClient = new ProjectClient(binding, address);
    
                projectClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel
                    = TokenImpersonationLevel.Impersonation;
    
                projectClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
    
                return projectClient;
    
            }
    
            private void queueWait(Guid jobId)
            {
                QueueSystemClient queueSystemClient = InitializeQueueClient();
                string xmlError;
                JobState jobState; // Status of the queue job 
                Thread.Sleep(DEFAULT_QUEUE_WAIT); // default sleep
    
                if (!projectSequence1.WorkflowContext.SkipToStage)
                {
                    Thread.Sleep(queueSystemClient.GetJobWaitTime(jobId)); // Estimated wait time sleep
                    while (true)
                    {
                        // Check job state.
                        jobState = queueSystemClient.GetJobCompletionState(out xmlError, jobId);
    
                        if (jobState == JobState.Success
                            || jobState == JobState.Unknown
                            || jobState == JobState.Failed
                            || jobState == JobState.FailedNotBlocking
                            || jobState == JobState.CorrelationBlocked
                            || jobState == JobState.Canceled)
                        {
                            break;
                        }
    
                        Thread.Sleep(DEFAULT_QUEUE_WAIT);
                    }
                }
                queueSystemClient.Close();
            }
    
            private void UpdateAndPublishProject(ProjectClient projectClient, ProjectDataSet projectDataSet)
            {
                Guid jobId = Guid.NewGuid();
                Guid SessionUid = Guid.NewGuid();
    
                // Force check-in
                projectClient.QueueCheckInProject(jobId, ProjectUid, true, SessionUid, "System Check-In");
                queueWait(jobId);
    
                // Check it out under this session
                SessionUid = Guid.NewGuid();
                projectClient.CheckOutProject(ProjectUid, SessionUid, "System Update");
    
                // Queue update, check-in and publish jobs
                jobId = Guid.NewGuid();
                projectClient.QueueUpdateProject(jobId, SessionUid, projectDataSet, false);
                jobId = Guid.NewGuid();
                projectClient.QueueCheckInProject(jobId, ProjectUid, false, SessionUid, "System Check-In");
                jobId = Guid.NewGuid();
                projectClient.QueuePublish(jobId, ProjectUid, true, null);
                queueWait(jobId);
    
            }
    
            private void UpdateCustomField(ProjectDataSet projectDataSet, Guid customFieldGuid, string fieldValue)
            {
                bool found = false;
    
                // Loop through the custom fields
                foreach (ProjectDataSet.ProjectCustomFieldsRow customFieldRow in projectDataSet.ProjectCustomFields)
                {
                    if (customFieldRow.MD_PROP_UID == customFieldGuid)
                    {
                        found = true;
                        customFieldRow.TEXT_VALUE = fieldValue;
                    }
                }
    
                if (!found)
                {
                    // Create a new row
                    ProjectDataSet.ProjectCustomFieldsRow customFieldRow =
                        projectDataSet.ProjectCustomFields.NewProjectCustomFieldsRow();
                    customFieldRow.PROJ_UID = ProjectUid;                 // Set the Project UID
                    customFieldRow.CUSTOM_FIELD_UID = Guid.NewGuid();     // The Custom_Field_UID is the unique identifier for each custom field row
                    customFieldRow.MD_PROP_UID = customFieldGuid;         // The MD_PROP_UID identifies the specific custom field
                    customFieldRow.TEXT_VALUE = fieldValue;               // Set the field value
    
                    // Add the row to the dataset
                    projectDataSet.ProjectCustomFields.AddProjectCustomFieldsRow(customFieldRow);
                }
    
            }
    
            private void UpdateProjectProperty(Guid projectFieldGuid, string propertyValue)
            {
                ProjectClient projectClient = InitializeProjectClient();
    
                // Get the project data set
                SvcProject.ProjectDataSet projectDataSet = projectClient.ReadProject(ProjectUid, SvcProject.DataStoreEnum.WorkingStore);
    
                // Update the desired custom fields, currently must be text value
                UpdateCustomField(projectDataSet, projectFieldGuid, propertyValue);
    
                // Update and publish the project
                UpdateAndPublishProject(projectClient, projectDataSet);
                projectClient.Close();
            }
    
            // Our ProjectStatus custom field
            private void SetProjectStatus(string status)
            {
                UpdateProjectProperty(ProjectStatusGuid, status);
            }
    
            // Methods used by workflow Code activities
            internal void SetProjectStatusRV_Impl(object sender, EventArgs args)
            {
                SetProjectStatus(WorkflowStrings.ProjectStatus_RV);
            }
    
            internal void SetProjectStatusXC_Impl(object sender, EventArgs args)
            {
                SetProjectStatus(WorkflowStrings.ProjectStatus_XC);
            }
    
    
    


    Tuesday, September 20, 2011 7:11 PM