The Project Server client-side object model implements common server functionality. The Project Server CSOM includes a Microsoft .NET CSOM and a JavaScript object model (JSOM). In addition, the CSOM includes an OData service that enables a REST interface.
Microsoft.ProjectServer.Client namespace:
CSOM can be accessed from on-premises Project Server installation and Project Online via Microsoft.Project.Server.Client namespace. It implements the key functionality for the major entities such as Task, Project, EnterpriseResource, andAssignment. It also takes in additional entities such as LookupTable, CustomField, EventHandler, WorkflowActivities, and QueueJob, which support other common Project Server functionality.
The CSOM is an API that is built on top of the PSI; it does not replace the PSI or implement all of the PSI functionality.
In CSOM extensions, the ProjectContext object provides the entry point to server content and functionality. The .NET CSOM uses the Microsoft.ProjectServer.Client.ProjectContext object to provide direct access to core Project Server objects in the current Project Web App site collection.
Below is the list of ProjectContext properties that represent Project Server objects. You can use these objects to retrieve other Project Server entities.
- CustomFields
- EnterpriseProjectTypes
- EnterpriseResources
- EntityTypes
- EventHandlers
- Events
- LookupTables
- Phases
- Projects
- Stages
- WorkflowActivities
- WorkflowDesigner
Steps for creating a CSOM project in Visual Studio:
Step 1: To create a CSOM project in Visual Studio
-
- Copy the following assemblies from the %ProgramFiles%Common FilesMicrosoft SharedWeb Server Extensions15ISAPIfolder to your development computer:
- Microsoft.ProjectServer.Client.dll
- Microsoft.SharePoint.Client.dll
- Microsoft.SharePoint.Client.Runtime.dll
- Copy the following assemblies from the %ProgramFiles%Common FilesMicrosoft SharedWeb Server Extensions15ISAPIfolder to your development computer:
.The Microsoft.ProjectServer.Client.dll assembly has dependencies on the related SharePoint assemblies.
-
- In Visual Studio, create a Console application and name the application, say CSOM_ForProjectOnline.
- In Solution Explorer, set references to the following assemblies:
- Microsoft.ProjectServer.Client.dll
- Microsoft.SharePoint.Client.dll
- Microsoft.SharePoint.Client.Runtime.dll
- In the Program.cs file, edit the using statements, as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ProjectServer.Client;
using Microsoft.SharePoint.Client;
using System.Security;
Step 2: Get the Project Context
- The code uses the pwaPath, userName & passWord constant along with static ProjectContext object.
class Program
{
const string pwaPath = “https://ServerName/pwa”; //Change the path to your
Project Web App instance
const string userName = “[email protected]”; //PWA Username
const string passWord = “password”; //PWA Password
static ProjectContext projectContext; //Initialize the ProjectContext Object
static void Main(string[] args)
{
}
}
- Add SharePointOnlineCredentials class which represents an object that provides credentials to access SharePoint Online resources.
static void Main(string[] args)
{
projectContext = new ProjectContext(pwaPath);
SecureString securePassword = new SecureString();
foreach (char c in passWord.ToCharArray())
{
securePassword.AppendChar(c);
}
projectContext.Credentials = new
SharePointOnlineCredentials(userName,securePassword);
}
- Firstly, let’s take an example to get list of Published Projects:
For this we create a new function ListPublishedProjects() and call it from main method as follows:
private static void ListPublishedProjects()
{
projectContext.Load(projectContext.Projects); //Load Project from PWA
projectContext.ExecuteQuery();
Console.WriteLine(“nList of all Published Projects:n”);
foreach (PublishedProject pubProj in projectContext.Projects)
{
Console.WriteLine(“nt{0}”, pubProj.Name);
}
Console.ReadLine();
PublishedProject class represents a project that is published on Project Server. Build and run the solution, and the output will be obtained on console as this:
Create New Project using CSOM:
Add new method CreateNewProject() to your Console Application as follows:
private static void CreateNewProject()
{
ProjectCreationInformation newProj = new ProjectCreationInformation();
newProj.Id = Guid.NewGuid();
newProj.Name = “Test Project”;
newProj.Description = “This Project is created via CSOM”;
newProj.Start = DateTime.Today.Date;
newProj.EnterpriseProjectTypeId =
new Guid(“09fa52b4-059b-4527-926e-99f9be96437a”);
PublishedProject newPublishedProj = projectContext.Projects.Add(newProj);
projectContext.Projects.Update();
projectContext.ExecuteQuery();
}
Here ProjectCreationInformation class specifies the information that is required to create a project.
Get list of Published Tasks of a Project using CSOM:
Add new method GetTasksOfProject () to your Console Application as follows:
private static void GetTasksOfProject()
{
projectContext.Load(projectContext.Projects); //Load Projects from PWA
projectContext.ExecuteQuery();
Guid ProjectGuid = new Guid(“b7dfde50-7a2d-e611-9bf8-681729bb2204”);
var project = projectContext.Projects.First(proj => proj.Id == ProjectGuid);
//Here you can also use the property proj.Name
projectContext.Load(project.Tasks); //Load Tasks of Project from PWA
projectContext.ExecuteQuery();
Console.WriteLine(“Tasks:n”);
foreach (PublishedTask task in project.Tasks)
{
Console.WriteLine(“nt{0}”, task.Name);
}
Console.ReadLine();
}
Output is obtained on console:
Create New Task using CSOM:
Add new method CreateNewTask() to your Console Application as follows:
private static void CreateNewTask()
{
Guid ProjectGuid = new Guid(“b7dfde50-7a2d-e611-9bf8-681729bb2204”);
var Project = projectContext.Projects.GetByGuid(ProjectGuid);
var draftProject = Project.CheckOut();
TaskCreationInformation task = new TaskCreationInformation();
task.Id = Guid.NewGuid();
task.Name = “New Task”;
task.Start = DateTime.Today.Date;
task.IsManual = false;
DraftTask draftTask = draftProject.Tasks.Add(task);
draftProject.Update();
draftProject.Publish(true); //Publish and check-in the Project
projectContext.ExecuteQuery();
}
Here TaskCreationInformation class specifies the information that is required to create a task.
Update Project Level Custom Field using CSOM:
Add new method UpdateProjectCF() to your Console Application as follows:
private static void UpdateProjectCF()
{
Guid CustomFieldGuid =new Guid(“99072634-db70-e611-80cb-00155da46e22”);
Guid ProjectGuid = new Guid(“3531cb1f-51ce-4a27-a45a-590339b99aed”);
var proj = projectContext.Projects.GetByGuid(ProjectGuid);
var draftProj = proj.CheckOut();
projectContext.Load(projectContext.CustomFields); //Load Custom Fields from PWA
projectContext.ExecuteQuery();
var CustomField = projectContext.CustomFields.First(CF => CF.Id == CustomFieldGuid);
//Here you can also use the property CF.Name
var CustomFieldValue= “New Value”;
string internalName = CustomField.InternalName.ToString(); //Get internal name of custom field
draftProj.SetCustomFieldValue(internalName, CustomFieldValue); //Set custom field value
draftProj.Publish(true); //Publish and check-in the Project
projectContext.ExecuteQuery();
}
Here customField.InternalName is the internal name of the custom field, reserved for internal use. In this code, internalName will be “Custom_99072634db70e61180cb00155da46e22”.
And the method draftProject.SetCustomFieldValue(internalName, CustomFieldValue) which sets a custom field on the project where CustomFieldValueis the value to be updated for the custom field.
Update Task Level Custom Field using CSOM:
Add new method UpdateProjectCF() to your Console Application as follows:
private static void UpdateTaskCF()
{
projectContext.Load(projectContext.Projects);//Load Projects from PWA
projectContext.ExecuteQuery();
projectContext.Load(projectContext.CustomFields);//Load Custom Fields from PWA
projectContext.ExecuteQuery();
Guid ProjectGuid = new Guid(“3531cb1f-51ce-4a27-a45a-590339b99aed”);
Guid TaskGuid = new Guid(“56b0ba40-da78-e611-80cb-00155da4672c”);
Guid CustomFieldGuid = new Guid(“3c3dfd8b-da78-e611-80cb-00155da4672c”);
var project = projectContext.Projects.GetByGuid(ProjectGuid);
DraftProject draftProject = project.CheckOut(); //CheckOut Project to make it editable
projectContext.Load(draftProject.Tasks);//Load tasks of Project
projectContext.ExecuteQuery();
var taskToEdit = draftProject.Tasks.First(task => task.Id == TaskGuid);//Get the task to be updated, Here you can also use the property task.Name
var CustomField = projectContext.CustomFields.First(CF => CF.Id == CustomFieldGuid);
var CustomFieldValue = “New Value”;
string internalName = CustomField.InternalName.ToString();//Get internal name of custom field
taskToEdit[internalName] = CustomFieldValue;//Set custom field value
draftProject.Publish(true);//Publish and Check-in the project
projectContext.ExecuteQuery();
}
Also, you can download the class file for all of the above functions here.
Hope you find this information helpful. In my upcoming blog, I will provide the code to perform Timesheet actions like Read, Save, Submit and Recall.