Creating an Extended Project List

Happy New Year all! I had a really nice holiday break at the end of December, I hope you all did too. As the New Year has dawned, so have more questions around Project Server 2007 development. I’ve actually been doing quite a bit of development on Project Server for a solution accelerator to Project Portfolio Server. Along with the questions, my solution accelerator has given me a number of ideas for posts, it’s just a matter of having time to get them “down on paper.”

One recurring use case is displaying a list of projects with their start and end dates (or any other basic information about a project like owner). After reading the SDK many people think that you can make just one call to get this information, even though the SDK is pretty good at pointing out you can’t, if you read deep enough. But heck we’re developers, we only read the whole page after something doesn’t work on the first try ( or after we debug it and can’t tweak it to work). The truth is you have to make one call to get the list of projects, followed by one call for each project to get the additional information.

So our first call would be the ReadProjectList… watch out not so quick. ReadProjectList is more intended for administrative application, it requires pretty high security clearances, ManageQueue and ManageSecurity privileges. The correct call here would be to ReadProjectStatus, which will return projects based on the current users permissions. I know, it’s a little convoluted, but don’t shoot the messenger. Here is an example of what that call might look like:

    ProjectWS.ProjectDataSet readProjDs = projectSvc.ReadProjectStatus(Guid.Empty,

        ProjectWS.DataStoreEnum.PublishedStore, string.Empty,

        (int)PSLibrary.Project.ProjectType.Project);

 

Our second call will be to loop on the returned dataset for each project. In the loop we will request the specific information for each project. To get the full dataset for a project we call ReadProject. Here is a sample:

    foreach (ProjectWS.ProjectDataSet.ProjectRow project in readProjDs.Project)

    {

        currentProjectDS = projectSvc.ReadProject(project.PROJ_UID,

            GetProjectList.ProjectWS.DataStoreEnum.PublishedStore);

        curProj = currentProjectDS.Project[0];

        Console.WriteLine(String.Format("{0} Starts {1}, Completes {2}",

            curProj.PROJ_NAME, curProj.PROJ_INFO_START_DATE.ToLongDateString(),

            curProj.PROJ_INFO_FINISH_DATE.ToLongDateString()));

    }

 

 The issue here is that ReadProject brings back the complete dataset, and we really only want a couple extra pieces of data from the Project table. There is a solution, use the ReadProjectEntities method. Think of ReadProjectEntities as ReadProject but with a filter on it, and conveniently a filter that you don’t need to build. If we modified the above sample to use ReadProjectEntities it might look like this:

    foreach (ProjectWS.ProjectDataSet.ProjectRow project in readProjDs.Project)

    {

        currentProjectDS = projectSvc.ReadProjectEntities(

            project.PROJ_UID, PROJECT_ENTITY_TYPE_PROJECT,

            ProjectWS.DataStoreEnum.PublishedStore);

        curProj = currentProjectDS.Project[0];

        Console.WriteLine(String.Format("{0} Starts {1}, Completes {2}",

            curProj.PROJ_NAME, curProj.PROJ_INFO_START_DATE.ToLongDateString(),

            curProj.PROJ_INFO_FINISH_DATE.ToLongDateString()));

    }

 

We now have an extra parameter to deal with called ProjectEntityType. The ProjectEntityType is really useful because you can combine the values together to get groups of entities. For example you could get the project and custom field tables only. Look in the Project Server 2007 SDK for further information on what values can be used as entity types.

I hope everyone finds this useful. Attached is the complete code sample for your consumption.

 

Program.cs