Project Server 2013 Remote Event Handlers

Code Samples, Office 365, Project Server, SharePoint

A new feature in Project Server 2013 is the Remote Event Handlers. Those who worked with 2010 version know that to write a server event one needed to:

– create an assembly containing the server event handlers
– create some code to register the server event handlers with the  Project Server events
– deploy the assembly to GAC on all the servers in the Project Server farm.

The easiest way to accomplish these tasks was to package everything in a solution that needed to be deployed in the farm. A feature Activate/ Deactivating handlers would take care of registering and unregistering the event handlers with the Project Server.

Now in 2013 these still apply, but there is also the possiblity to create so-called Remote Event Handlers. This new feature enables responding to server side events without having to deploy any code in the farm. This is especially useful for those having their Project instance in the cloud (Office 365), or wherever company IT policies prohibit deploying code to the SharePoint farm.

To create a remote event handler, the tasks above become:

– create a WCF service (in an existing web application, or in a new web application) that implements the desired event(s)
– have some code to register the endpoint to this WCF service with the Project Server events

The WCF service can be hosted in a  web application on premises or in cloud as long as there’s direct HTTP(s) communication between the Project Server farm and the Remote event handler it will work.

Below there is a small code sample to illustrate this concept. We will be connecting to a Project Server farm, and write a remote event handler for the ProjectCreating event which will fail creation for those projects that do not respect certain naming convention. Let’s assume that our managers don’t want the word “New” in the project name.

We start with a New empty web application project – let’s call it ProjServerRemoteEventDemo, to which we add 2 things – an empty Web Form page (default.aspx) and a WCF service called ProjectEventReceiver.svc.

We also need to add a few references:

– Project Server library (Microsoft.Office.Project.Server.Library.dll)
– Project Server event receivers definitions (Microsoft.Office.Project.Server.Event.Receivers.dll)
– Project Server CSOM (Microsoft.ProjectServer.Client.dll) which in turn requires
– SharePoint CSOM (Microsoft.SharePoint.Client.dll) and
– SharePoint CSOM runtime (Microsoft.SharePoint.Client.Runtime.dll).

These files can be easily found browsing to C:WindowsMicrosoft.NETassemblyGAC_MSIL in their folders.

Default.aspx will serve as an interface to the register/unregister functions. We will use CSOM to manage event registration:

 

In the code behind, registration management is done on btnRegister_Click and btnUnregister_Click. The brief code for these two methods is below:

Register_Click:


ProjectContext pc = new ProjectContext(ProjectServerUrl);
pc.EventHandlers.Add(new EventHandlerCreationInformation()
{
EndpointUrl = BaseUrl + "/ProjectEventReceiver.svc",
Id = EventHandlerUid,
Name = "Project OnCreating Demo Event",
EventId = (int)PSEventID.ProjectCreating,
Order = 1,
CancelOnError = true
});
pc.EventHandlers.Update();
pc.ExecuteQuery();

Let’s detail a bit:

ProjectServerUrl is the address for your PWA instance (say http://projects.contoso.com/pwa)
BaseUrl is the address where the event receiver is published (say http://cloud-app.contoso.com/)
Some important properties that are set in the EventHandlerCreationInformation class are:
–  Id: this gives an unique event registration Id – it will allow us to retrieve the event later when we want to unregister it.
– EventId: this specifies which event are we attaching to, in our case PSEventId.ProjectCreating
– Order: event handler calling order
– EndpointUrl: where is the WCF endpoint that will handle the event.

 

Unregister_Click:

ProjectContext pc = new ProjectContext(ProjectServerUrl);
pc.Load(pc.EventHandlers);
EventHandler evh = pc.EventHandlers.GetByGuid(EventHandlerUid);
pc.Load(evh);
pc.ExecuteQuery();
pc.EventHandlers.Remove(evh);
pc.EventHandlers.Update();
pc.ExecuteQuery();

A very important thing to note is that the registration and unregistration of event handlers is not a synchronous process. It is done in a timer job that runs quite frequently but still there will be a few seconds delay from the moment the ExecuteQuery() returns and the actual event registration.

Now that we have finised with registration, let’s concentrate on the event handler itself.

As expected, for the eventing subsystem in the Project Server to be able to talk to our WCF service, the latter needs to implement a specific contract. In our case this contract is IProjectEventReceiverRemote which is defined in the Microsoft.Office.Project.Server.Event.Receivers.dll assembly togheter with other contracts. These are distinguished by the termination “Remote”.

The actual implemetation is straightforward:


public class ProjectEventReceiverRemoteService : IProjectEventReceiverRemote
{

public ProjectPreEventArgs OnCreatingRemote(Microsoft.Office.Project.Server.Library.PSContextInfo contextInfo, Guid eventHandlerUid, ProjectPreEventArgs e)
{
if (e.ProjectName.Contains(“New”))
{
e.CancelReason = “Naming requirements not met. Please remove ‘New’ from project name”;
e.Cancel = true;
}
return e;
}


}

Remote Event handler for ProjectCreating

Having these, the project is complete. Let’s  compile and start the web application, then register the event. when a project that has “New” in name is created, this is what we get:

Cancelling creation of new projects if they contain New in name

 

The sample solution files are available: ProjServerRemoteEventDemo.

What do you think?

  • Great post!
    Quick question: when I go to http://localhost:65196/ProjectEventReceiver.svc I see “Could not load file or assembly ‘Microsoft.SharePoint.Client.ServerRuntime, Version=15.0.0.0′”.
    Any ideas where can I locate this dll? I have downloaded SharePoint Server 2013 Client Components but it’s not there..

  • Hi,

    I follow the post and successfully setup the WCF on IIS, the WCF works fine with the on premises, but when I tried Project Online, the event is not fire, any idea? ( I can register/un-register the event without any problem)

    Thanks!

    • If you are already using SSL, please make sure that the site hosting the handlers allows anonymous access, and the service bindings configuration is correct.

  • hi,,i checked the above process remote event handlers ,but it is not working for project events like project creating or project publishing events
    ,,,when i am creating event handler On projectcreating it is getting blocked in queue jobs… and is working for resource event…can u please help i want to create a project event on project publishing or published..plzzzz help

  • I followed your post and created a solution to deploy the Project server event remotely. But when I am executing the code the event is not getting registered. There is no error being thrown ,no error in queue. Can,you help me identifying what can be cause for event not getting registered. I tried with your sample code but also then same behavior.