EPMFAQ
Project Server Help, FAQs, Blogs, and HowTos
This is The Header Then

Retrieve the Guid of a Custom Field Using its Name

posted May 7th, 2008 by Stephen Sanderlin
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Within the Project Object Model, the Application object has a method, FieldNameToFieldConstant(), that returns a PjField constant for use by the various SetField() and GetField() methods throughout the object model. More information on the SetField Method (and other associated methods) can be found here.

Unfortunately, when using the PSI, there’s no quick way to lookup the Guid for a field. This can be a problem, since the various CustomFieldsRow objects (Task, Resource, Assignment, and Project) do not include the name of the custom field, only the UID (for an example, look at the ProjectCustomFieldsRow entity in the Project 2007 SDK).

Retrieving custom field information in the PSI is accomplished by using the CustomFields web service. The code below is a class that implements a method to retrieve the Guid of a custom field using the field’s name and entity type. I had to chop the code up a lot because of space constraints, so I apologize for the excessive line breaks. This code assumes that you’ve set up a Web Reference to the CustomFields web service named WebSvcCustomFields.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Net;

    4 using System.Text;

    5 using System.Windows.Forms;

    6 using PSLib = Microsoft.Office.Project.Server.Library;

    7 

    8 namespace EPMFAQ.StephenSanderlin.ProjectServer2007.CustomLookups

    9 {

   10     public class FieldNameToGuid

   11     {

   12         #region Methods

   13         /// <summary>

   14         /// Queries the PSI for a Custom Field matching the given name with

   15         /// the proper entity type.

   16         /// </summary>

   17         /// <param name=”validProjectServerCredentials”>Validated IWA

   18         /// Network Credentials.</param>

   19         /// <param name=”validProjectServerUri”>Valid Project Server

   20         /// Uri.</param>

   21         /// <param name=”validProjectServerCookie”>Cookie issued by

   22         /// Project Server upon login.</param>

   23         /// <param name=”customFieldName”>String representing the name of

   24         /// the custom field we wish to retrieve the GUID for.</param>

   25         /// <param name=”desiredEntityType”>GUID of the desired

   26         /// entity type. Retrieve from

   27         /// Microsoft.Office.Project.Server.

   28         /// Library.EntityCollection.</param>

   29         /// <returns>Guid.Empty if nothing is found or a GUID representing

   30         /// the field.</returns>

   31         /// <example>GetFieldNameUsingGuid(Credentials, Uri,

   32         /// CookieContainer, “Project Origin”, new

   33         /// Guid(Microsoft.Office.Project.Server.Library.

   34         /// EntityCollection.Entities.ProjectEntity.UniqueId))</example>

   35         public static Guid GetGuidUsingFieldName

   36             (NetworkCredential validProjectServerCredentials,

   37             Uri validProjectServerUri,

   38             CookieContainer validProjectServerCookie,

   39             string customFieldName, Guid desiredEntityType)

   40         {

   41             WebSvcCustomFields.CustomFields _cf =

   42                 new WebSvcCustomFields.CustomFields();

   43             const string _cfUrl = “_vti_bin/PSI/CustomFields.asmx”;

   44             PSLib.EntityCollection _entityType =

   45                 new PSLib.EntityCollection();

   46             Guid _returnedGuid = Guid.Empty;

   47             WebSvcCustomFields.CustomFieldDataSet _cfDataSet =

   48                 new WebSvcCustomFields.CustomFieldDataSet();

   49             WebSvcCustomFields.CustomFieldDataSet.CustomFieldsRow

   50                 _cfRow;       

   51             PSLib.Filter _cfFilter = new PSLib.Filter();

   52             PSLib.Filter.FieldOperationType _equal =

   53                 PSLib.Filter.FieldOperationType.Equal;

   54 

   55             string _tableName =

   56                 _cfDataSet.CustomFields.TableName;

   57             string _nameColumn =

   58                 _cfDataSet.CustomFields.MD_PROP_NAMEColumn.ColumnName;

   59             string _uidColumn =

   60                 _cfDataSet.CustomFields.MD_PROP_UIDColumn.ColumnName;

   61             string _entityUidColumnName =

   62                 _cfDataSet.CustomFields.MD_ENT_TYPE_UIDColumn.ColumnName;

   63 

   64             try

   65             { 

   66                 _cf.Credentials = validProjectServerCredentials;

   67                 _cf.Url = validProjectServerUri.AbsoluteUri + _cfUrl;

   68                 _cf.CookieContainer = validProjectServerCookie;

   69 

   70                 // Set up the filter

   71                 _cfFilter.FilterTableName = _tableName;

   72                 _cfFilter.Fields.Add

   73                     (new PSLib.Filter.Field(_tableName, _nameColumn));

   74                 _cfFilter.Fields.Add

   75                     (new PSLib.Filter.Field(_uidColumn));

   76                 _cfFilter.Criteria =

   77                     new PSLib.Filter.LogicalOperator

   78                         (PSLib.Filter.LogicalOperationType.And,

   79                     new PSLib.Filter.FieldOperator

   80                         (_equal, _entityUidColumnName, desiredEntityType),

   81                     new PSLib.Filter.FieldOperator

   82                         (_equal, _nameColumn, customFieldName));

   83 

   84 

   85                 _cfDataSet =

   86                     _cf.ReadCustomFields(_cfFilter.GetXml(), false);

   87 

   88                 // We should only get one result back

   89                 if (_cfDataSet.CustomFields.Rows.Count == 1)

   90                 {

   91                     _cfRow = (WebSvcCustomFields.

   92                         CustomFieldDataSet.CustomFieldsRow)

   93                         _cfDataSet.CustomFields.Rows[0];

   94                     _returnedGuid = _cfRow.MD_PROP_UID;

   95                 }

   96 

   97                 else

   98                 {

   99                     return Guid.Empty;                   

  100                 }

  101             }

  102 

  103             catch (System.Web.Services.Protocols.SoapException ex)

  104             {

  105                 MessageBox.Show(ex.Message.ToString(), “SOAP Error”,

  106                     MessageBoxButtons.OK, MessageBoxIcon.Error);

  107             }

  108 

  109             catch (System.Net.WebException ex)

  110             {

  111                 MessageBox.Show(ex.Message.ToString(), “Web Error”,

  112                     MessageBoxButtons.OK, MessageBoxIcon.Error);

  113             }

  114 

  115             return _returnedGuid;

  116         }

  117         #endregion   

  118     }

  119 }

The GetGuidUsingFieldName() method takes five parameters (validProjectServerCredentials, validProjectServerUri, validProjectServerCookie, customFieldName, and desiredEntityType) that supply the necessary information. This method returns a Guid, which is the Guid of the requested field. If no field exists, an empty Guid will be returned.

First, we set up our various local fields on lines 41-62 (including setting up a field to represent the Equal operation type for a filter on lines 52-53). We set up fields to hold column and table names in the CustomFieldDataSet on lines 55-62. While lines 54-61 are not strictly necessary, this is a personal habit — I do this only to make the later method calls more succinct.

We configure the Web Reference on lines 66-68, and then begin to set up the filter parameters. Basically, we are constructing a filter to return only results with the desired custom field name and entity type.

Then, on lines 85-86, we call the ReadCustomFields method in the CustomFields web service. We should recieve only one entry back — if we recieve multiple rows (or none at all), we return an empty Guid. Obviously, in production code, we would want some more robust error handling here, but that is left as an exercise to the reader. Assuming we recieve only one result, we extract the Guid on lines 91-94 and return it on line 115.

This method provides a quick way to retrieve the Guid of a field, thereby approximating the FieldNameToFieldConstant() in the Object Model.

When implementing this code, it’s important to remember that constantly going to the PSI is an expensive process. You do not want to call this method every single time you need a Guid for a field. Therefore, I would recommend that you implement a form of the Lazy Initializtion design pattern which would check a Hashtable (using the field name as the key, and the Guid as the value) that stores the name and Guid of the fields your application uses. You can then simply check the Hashtable to see if the value has been retrieved — if it has not, then you would use the above code to retrieve it and then store it in the hashtable. If your application is long-running, you will want to implement some sort of periodic verification to make sure the Guid you’ve retrieved is still valid. A slight variation of the above code would accomplish this easily. The other obvious alternative is to front-load the retrieval during application startup. While the method discussed above is the more “elegant” solution, front-loading is entirely adequate. However, I would recommend that you spawn off another thread to get the data rather than holding up your startup process.

However you choose to implement the above code, it is a significantly more robust alternative to hardcoding in the Guids.

As always, please feel free to post any comments, feedback, errors, or issues in the EPMFAQ Blog Posts Forum.


Stephen Sanderlin is Vice President of Technology for MSProjectExperts and a Microsoft Project MVP. His earlier writings on Project Management and Microsoft Project can be read at EPMFAQ.
He is actively posting new content at ProjectServerHelp.

Popularity: 52%




Discuss this post on the EPMFAQ Blog Posts Forum.


Related Posts

  • No Related Posts



« Previous Entry Next Entry »

Please discuss this post on the EPMFAQ Blog Posts Forum.

2 Responses to “Retrieve the Guid of a Custom Field Using its Name”


  1. […] Stephen Sanderlin wrote an interesting post today on Retrieve the Guid of a Custom Field Using its NameHere’s a quick excerpt2 using System.Collections.Generic;. 3 using System.Net;. 4 using System.Text;. 5 using System.Windows.Forms;. 6 using PSLib = Microsoft.Office.Project.Server.Library;. 7. 8 namespace EPMFAQ.StephenSanderlin.ProjectServer2007. … […]


  2. […] best way to get them is to use the CustomFields web service. I have some sample code posted here: http://www.epmfaq.com/ssanderlin/pro…using-its-name — Stephen Sanderlin Principal Consultant MSProjectExperts For Project Server Consulting: […]


The opinions expressed on this site by the authors and those providing comments are theirs alone, and do not reflect the opinions of the respective employers of the authors or any employee thereof. Our respective employers are not responsible for the accuracy of any of the information supplied by on this site.

Terms of Use | Privacy Policy | Publishers

All content on this website is covered by the
Creative Commons Attribution-Share Alike 3.0 United States License.
Theme ©2007 The Heckerped WordPress Theme created by JTk of Doc5 under the Creative Commons Attribution License.