How to update a CF in Event Handler RRS feed

  • Question

  • Hi people!

    The question is pretty simple (I don´t know how complicated is the solution), how to update a CF in the OnCreating or OnCreated PS Event Handler??

    There is difference between two Handlers: OnCreating has the DataSet and OnCreated not.

    I´ve tried to update the dataset on OnCreating Handler, but no sense. At the OnCreated Event I´ve tried to get the Project Web Service and update by QueueAddToProject, but the Queue get stucked at that point...

    Any helps?!?!


    Miguel Soler

    Friday, March 23, 2012 1:06 AM

All replies

  • Hi Miguel,

    If i understood your requirement correctly, You are trying to update the value of a project level custom field on project creating/created. Recently, I worked with a customer with the similar set of requirement. Whenever a project is created, Based on other fields CF values also, my event handler assigns specific department to project. It used the OnCreating event handler.

    Here is a sample code which I extended for my requirement.

    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    using System.ServiceModel;
    using System.Security.Principal;
    using Microsoft.SharePoint;
    using Microsoft.Office.Project.Server.Events;
    using PSLib = Microsoft.Office.Project.Server.Library;
    using PSSchema = Microsoft.Office.Project.Server.Schema;
    namespace TestCreatingProject
        public class AssignProjectDepartment : ProjectEventReceiver
            // Change the department name to match a department in your installation.
            private const string PROJECT_DEPARTMENT2CHECK = "Test Dept 2";
            private const string EVENT_SOURCE = "Project Event Handler";
            private const int EVENT_ID = 5050;
            private static SvcLookupTable.LookupTableClient lookupTableClient;
            private EventLog eventLog;
            // Change the output directory for your computer.
            private const string OUTPUT_FILES = @"C:\Project\Samples\Output\";
            private static string outFilePath;
            public override void OnCreating(PSLib.PSContextInfo contextInfo, ProjectPreEventArgs e)
                base.OnCreating(contextInfo, e);
                // Create an EventLog instance and assign its source.
                eventLog = new EventLog();
                eventLog.Source = EVENT_SOURCE;
                string logEntry = string.Empty;
                // Get information from the event arguments.
                string userName = contextInfo.UserName;
                Guid pwaUid = contextInfo.SiteGuid;
                string projectName = e.ProjectName;
                Guid projectUid = e.ProjectGuid;
                PSSchema.ProjectDataSet projDs = e.ProjectDataSet;
                // Write the ProjectDataSet to a file, for debugging purposes.
                outFilePath = OUTPUT_FILES + "ProjectDataSet4CreatingEventHandler.xml";
                e.Cancel = false;
                // Get the GUID of the default Project Department custom field.
                Guid projDeptCFMdPropUid = PSLib.CustomField.PROJECT_DEPARTMENT_MD_PROP_UID;
                Guid projDeptUid = Guid.Empty;
                for (int i = 0; i < projDs.ProjectCustomFields.Rows.Count; i++)
                    if (projDs.ProjectCustomFields[i].MD_PROP_UID == projDeptCFMdPropUid)
                        projDeptUid = projDs.ProjectCustomFields[i].CODE_VALUE;
                int numTasks = projDs.Task.Rows.Count;
                string departmentName = GetDepartmentValue(pwaUid, projDeptUid);
                if (projDeptUid != Guid.Empty)
                    if (departmentName == PROJECT_DEPARTMENT2CHECK && numTasks > 3)
                        e.Cancel = true;
                WriteLogEntries(e.Cancel, numTasks, departmentName, userName, projectName);

    For more information, try using the SDK's sample of Eventhandler solution.

    Hope that helps.

    Thanks, Amit Khare |EPM Consultant| Blog:

    Friday, March 23, 2012 5:30 AM
  • Hi Amit,

    Thanks for your time answering me, now I would try to be more concrete:

     I´ve already used that sample to start too, but as you know, in this code, there is no example to update a CF.

    I´ve tried this code:

    PSSchema.ProjectDataSet.ProjectCustomFieldsRow prow = e.ProjectDataSet.ProjectCustomFields.NewProjectCustomFieldsRow();
    prow.PROJ_UID = e.ProjectGuid;
    prow.CUSTOM_FIELD_UID = Guid.NewGuid();
    prow.MD_PROP_UID = new Guid(CFIdProyecto);
    prow.TEXT_VALUE = departmentName;
    base.OnCreating(contextInfo, e);

    This code is executed without any errors, but the CF is not updated neither created. What do I need to add to that code or maybe do I have to change for another one?

    Please share your solution or a piece of.


    Miguel Soler

    Friday, March 23, 2012 8:38 AM
  •  Interesting I've done it onCheckIn and on Published but not at this point of its lifecycle. The project definitely has a project dataset object at that stage.

    Reading the evidence above I'm thinking the answer could lie in the fact that you said during the creating event it has a dataset and then at the end of the create phase (onCreated) there is no dataset. So if no dataset then you lost your mods silently as your 'code is executed without any errors...'.

    Are you sure there is no dataset at the onCreated event stage? Strange that the project would have a dataset part way through the create cycle.

    Ray Letts Arbutus Solutions

    Sunday, March 25, 2012 6:49 AM
  • Hi Ray,

    At the OnCreated event, you can have access directly to :

    PSContextInfo contextInfo, ProjectPostEventArgs e

    On the OnCreating event you have access to:

    PSContextInfo contextInfo, ProjectPreEventArgs e

    The ProjectPreEvents object has a ProjectDataSet, and by it we can obtein all the Project information, but I was wondering that also we can modify it to make sense at the late project information, but I don´t know how. The code I´ve posted above "e.ProjectDataSet.ProjectCustomFields.NewProjectCustomFieldsRow();" This object "e" is referring to the ProjectPreEvents object...

    On the OnCreated event I can get the ProjectUID from the ProjectPostEventArgs object and after I get it, I can use the Project.asmx web service to read and try to update. This is very weird, I have to get the SessionID that is used in that moment because I cannot cancell the OnCreated event...

    I guess I´m doing something strange or something misunderstood... Any questions and answers would be apreciated!


    Miguel Soler

    Sunday, March 25, 2012 10:34 AM
  •   Hmm I get the dataset a different way. Here is the relevant code:

    public override void OnPublished(PSLibrary.PSContextInfo contextInfo, ProjectPostPublishEventArgs e)
            {//use this method as you do, that is same arguments.

    however in a method I wrote I use this call to get the dataset

    {        public void getProjectDataSet()

                    logString = " Accessing ProjectDataSet();";
                    projectDs = new backendProject.ProjectDataSet();
                    projectDs = projectClient.ReadProject(projectGuid, backendProject.DataStoreEnum.PublishedStore);

                    //do not get quote id/number from custom field as key now
                    //Use project name since it is unique and in quote list as key
                catch (Exception ex)....

    So I read it via the WCF web service not the asmx web service which is deprecated and may dissapear with the next release of project server. I would suggest using the WCF.

    I used this series of posts a couple of years back to develop my project event handler to read and set custom fields.  especially this one on creating a project server event handler.

    good luck!


    Ray Letts Arbutus Solutions

    Sunday, March 25, 2012 7:49 PM