Adding a Project to a Category
Brian Smith from PSS has passed along this sample that we thought might be helpful:
The scenario here is that you have a lookup table that shows the categories you want users to select from when creating a project, and then the GUID for the "real" security category is held in the description for the lookup table value. You make the CF that feeds from the Lookup Table a required Project Level text field. The Project.Created event fires and the dataset is read - the custom field identified and the GUID of the security category is then used to add the project to the security category.
No error checking or exception handling is shown - you can do this bit. You would also need to set the categories to the rule "only projects...". I've hardcoded my lookup table and a reference required to the Microsoft.Office.Project.Server.Library and Events. A Web References to LookupTable, Project, Security and LoginWindows is also required.
The code will run as the user running the services - so you will either need that account to have PWA permissions or to change to use impersonation.
using System;
using System.Collections.Generic;
using System.Net;
using System.Diagnostics;
using System.Text;
using Microsoft.Office.Project.Server.Events;
using Microsoft.Office.Project.Server.Library;
namespace TestEventHandler
{
public class AutoCategory:ProjectEventReceiver
{
public override void OnCreated(PSContextInfo contextInfo, ProjectPostEventArgs e)
{
// cfGuid holds CF for Project Category
Guid cfGuid = new Guid("9bbc698f-5c1d-4f8d-a3d0-163006416bf2");
// ltGuid holds LT for Categories
Guid ltGuid = new Guid("625bab60-4427-4f0b-941b-9860d1293338");
// lt_Struct_Uid gets the id for the selected LT value
Guid lt_Struct_Uid = new Guid("00000000-0000-0000-0000-000000000000");
// securityCategoryGuid gets the Security Categorty Guid from the Descriptio field in the lookup table
Guid securityCategoryGuid = new Guid("00000000-0000-0000-0000-000000000000");
// 32 is used to just get the CF entities from the readProjectEntities
const int PROJECT_ENTITY_TYPE_PROJECTCUSTOMFIELD = 32;
Guid SECURITY_CATEGORY_OBJECT_TYPE_PROJECT = new Guid("1771B1C0-6E26-4FB3-A480-C798AB506E82");
WebSvcLoginWindows.LoginWindows loginWindows = new TestEventHandler.WebSvcLoginWindows.LoginWindows();
WebSvcProject.Project project = new TestEventHandler.WebSvcProject.Project();
WebSvcSecurity.Security security = new TestEventHandler.WebSvcSecurity.Security();
WebSvcLookupTable.LookupTable lookupTable = new TestEventHandler.WebSvcLookupTable.LookupTable();
//login to Project Server - this assumes the event service has a login with permissions
// Impersonation would be better
loginWindows.Url = @"https://SERVER_NAME/ProjectServer/_vti_bin/PSI/LoginWindows.asmx";
loginWindows.Credentials = CredentialCache.DefaultCredentials;
loginWindows.Login();
// Get the dataset
project.Url = @"https://SERVER_NAME/ProjectServer/_vti_bin/PSI/Project.asmx";
project.Credentials = CredentialCache.DefaultCredentials;
lookupTable.Url = @"https://SERVER_NAME/ProjectServer/_vti_bin/PSI/LookupTable.asmx";
lookupTable.Credentials = CredentialCache.DefaultCredentials;
security.Url = @"https://SERVER_NAME/ProjectServer/_vti_bin/PSI/security.asmx";
security.Credentials = CredentialCache.DefaultCredentials;
WebSvcProject.ProjectDataSet dsProjectDataSet = new TestEventHandler.WebSvcProject.ProjectDataSet();
dsProjectDataSet = project.ReadProjectEntities(e.ProjectGuid, PROJECT_ENTITY_TYPE_PROJECTCUSTOMFIELD, TestEventHandler.WebSvcProject.DataStoreEnum.WorkingStore);
for (int i = 0; i < dsProjectDataSet.ProjectCustomFields.Count; i++)
{
if (dsProjectDataSet.ProjectCustomFields[i].MD_PROP_UID == cfGuid)
{
lt_Struct_Uid = dsProjectDataSet.ProjectCustomFields[i].CODE_VALUE;
}
}
Guid[] arrayLtUid = new Guid[1]{ltGuid};
WebSvcLookupTable.LookupTableDataSet dsLookupTable = new TestEventHandler.WebSvcLookupTable.LookupTableDataSet();
dsLookupTable = lookupTable.ReadLookupTablesByUids(arrayLtUid, false, 1033);
for (int i = 0; i < dsLookupTable.LookupTableTrees.Count; i++)
{
if (dsLookupTable.LookupTableTrees[i].LT_STRUCT_UID == lt_Struct_Uid)
{
securityCategoryGuid = new Guid(dsLookupTable.LookupTableTrees[i].LT_VALUE_DESC.ToString());
}
}
WebSvcSecurity.SecurityCategoriesDataSet dsSecurityCategories
= new TestEventHandler.WebSvcSecurity.SecurityCategoriesDataSet();
// Read the existing values for the security category into the dataset
dsSecurityCategories = security.ReadCategory(securityCategoryGuid);
// Get a new objects row to put the created project into
WebSvcSecurity.SecurityCategoriesDataSet.SecurityCategoryObjectsRow dsSecurityCategoryObjectsRow
= dsSecurityCategories.SecurityCategoryObjects.NewSecurityCategoryObjectsRow();
//Set the values
dsSecurityCategoryObjectsRow.WSEC_OBJ_TYPE_UID = SECURITY_CATEGORY_OBJECT_TYPE_PROJECT;
dsSecurityCategoryObjectsRow.WSEC_CAT_UID = securityCategoryGuid;
dsSecurityCategoryObjectsRow.WSEC_OBJ_UID = e.ProjectGuid;
// Add the row to the dataset and then pass to SetCategories to update
dsSecurityCategories.SecurityCategoryObjects.AddSecurityCategoryObjectsRow(dsSecurityCategoryObjectsRow);
// Create an EventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "Project Event Handler";
// Get information from the event arguments, and
// write an entry to the Application event log.
string userName = contextInfo.UserName.ToString();
string projectName = e.ProjectName.ToString();
string secCatUid = securityCategoryGuid.ToString();
int eventId = 3652;
string logEntry;
logEntry = "User: " + userName +
"\nProject: " + projectName +
"\nSecurity Category Uid: " + secCatUid;
myLog.WriteEntry(logEntry, EventLogEntryType.Information, eventId);
security.SetCategories(dsSecurityCategories);
}
}
}