none
project server 2010: reading custom resource fields through PSI RRS feed

  • Question

  • Hi,

    Can anyone inform me or give me an example or link that shows how to read a custom field of a resource? I have added a resource custom field from the Server Settings -> Enterprise Data -> Enterprise Custom Fields and Lookup Tables. The custom field is of String type and not mandatory. I need to read this field programmatically by using the PSI.

    Regards,
    George

    Wednesday, February 2, 2011 11:20 AM

Answers

  • See the ReadResource method in the SDK. You'd look in the ResourceDataSet.ResourceCustomFields table.


    Jim Corbin [MSFT]
    • Proposed as answer by Jim Corbin Wednesday, February 2, 2011 4:28 PM
    • Marked as answer by geo_d Thursday, February 24, 2011 1:37 PM
    Wednesday, February 2, 2011 4:27 PM
  • Thanks George,
    I was already able to build an xml filter using PSLib.Filter.Field objects as you wrote in your example.
    Anyway thanks to your last suggestion I resolved my issue in this way:

    PSLib.Filter resourceFilter = new PSLib.Filter();
    //resourceFilter.FilterTableName = dsResource.ResourceCustomFields.TableName;
    resourceFilter.FilterTableName = dsResource.Resources.TableName;

    resourceFilter.Fields.Add(new PSLib.Filter.Field(dsResource.Resources.TableName, dsResource.Resources.RES_UIDColumn.ColumnName, PSLib.Filter.SortOrderTypeEnum.None));
    resourceFilter.Fields.Add(new PSLib.Filter.CustomField(dsResource.ResourceCustomFields.TableName, new Guid("1945c571-5405-490a-b84f-af047c34d0ff"), PSLib.Filter.PropertyTypeEnum.TextValue));

    Notice that if I set the FilterTableName property with "ResourceCustomFields" table name PSI comes out with a "ResourceFilterInvalid" error (description is: "Join _Resources_ is missing from provided joins").
    Conversely if I use the "Resources" table name PSI works properly (somehow strange to me).

    Then I filtered my resources with OR logical operators in the criteria:

    Guid[] guidElementi = new Guid[] { new Guid("46f296e3-2b34-4900-836f-10cab51098d3"),
                                       new Guid("e5c6aef7-08a6-4a3c-aafc-20369822dcd0"),
                                       new Guid("246877a3-1933-4cd6-8c01-24abe13377fe"),
                                       new Guid("5c3428e3-5bd4-45ee-a77f-2f8463b653d8")};

    PSLib.Filter.IOperator[] fos = new PSLib.Filter.IOperator[guidElementi.Length];
    for (int i = 0; i < guidElementi.Length; i++) {
      fos[i] = new PSLib.Filter.FieldOperator(PSLib.Filter.FieldOperationType.Equal, sCampoChiaveElem, guidElementi[i]);
    }
    PSLib.Filter.LogicalOperator lo = new PSLib.Filter.LogicalOperator(PSLib.Filter.LogicalOperationType.Or, fos);
    resourceFilter.Criteria = lo;

    string resourceAssignmentFilterXml = resourceFilter.GetXml();
    dsResource = AdminUtils.svcResource.ReadResources(resourceAssignmentFilterXml, false);

    Thank you very much for your kind support.

    Daniele

    • Marked as answer by geo_d Friday, March 4, 2011 9:14 AM
    Thursday, March 3, 2011 5:53 PM

All replies

  • See the ReadResource method in the SDK. You'd look in the ResourceDataSet.ResourceCustomFields table.


    Jim Corbin [MSFT]
    • Proposed as answer by Jim Corbin Wednesday, February 2, 2011 4:28 PM
    • Marked as answer by geo_d Thursday, February 24, 2011 1:37 PM
    Wednesday, February 2, 2011 4:27 PM
  • Hi, I have another problem with resource custom field reading.

    I successfully managed to read resource custom fields using the "ReadResource" web method of Resource service accessing the ResourceCustomFields datatable after the call.

    I actually need to read a *group* of resources and access all their custom fields  in a single web method call. I tried the "ReadResources" method but I noticed it doesn't populate the ResourceCustomFields datatable as the "ReadResource" does.

    Is there any way to achieve this?

    Thanks in advance.

    Wednesday, March 2, 2011 11:20 AM
  • Hi dmin72,

    I'm not sure about it but I guess this is possible. You just have to add the custom field you want to read in the xmlfilter. You need something like this:

    resourceFilter.Fields.Add(new PSLibrary.Filter.CustomField(resourceDs.ResourceCustomFields.TableName, resourceDs.ResourceCustomFields.CODE_VALUEColumn, PSLibrary.Filter.SortOrderTypeEnum.None));

    Please do not copy paste what I have written above, this is just a sample for you to understand what you need to do.

    Hope this helps.

    Regards,
    George

    Wednesday, March 2, 2011 11:39 AM
  • Hi George, thanks for your useful advice.
    I have another problem now.

    I set up my filter in this way:

    WebSvcResource.ResourceDataSet dsResource = new WebSvcResource.ResourceDataSet();
    PSLib.Filter resourceFilter = new PSLib.Filter();
    resourceFilter.FilterTableName = dsResource.ResourceCustomFields.TableName;
    resourceFilter.Fields.Add(new PSLib.Filter.CustomField(dsResource.ResourceCustomFields.TableName, new Guid("1945c571-5405-490a-b84f-af047c34d0ff"), PSLib.Filter.PropertyTypeEnum.TextValue));

    PSLib.Filter.CustomField datatable have a slightly different constructor from what you wrote: first parameter is the table name, second is the UID of the custom field (I suppose the content of MD_PROP_UID field of the ResourceCoustomField datatable) and third is the type of fields (in my case a text value one).

    When I try to call the method ReadResource as follows:

    string resourceAssignmentFilterXml = resourceFilter.GetXml();
    dsResource = svcResource.ReadResources(resourceAssignmentFilterXml, false);

    PSI simply returns null into dsResource.
    I verified that custom field is present in several resources.
    What am I doing wrong?

    Thanks for your help. 

    Thursday, March 3, 2011 10:44 AM
  • Hi,

    I assume you are not allowed to only return the customfield value. You need to add another field such as the customFieldUID or the resourceUID (something to resemble a key for the returned data). You can read more on the xmlfilter in the sdk. An example without the customfield would be:

                    PSLibrary.Filter resourceFilter = new Microsoft.Office.Project.Server.Library.Filter();
                    resourceFilter.FilterTableName = resourceDs.Resources.TableName;
                    resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_UIDColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
                    resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_NAMEColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
                    resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.RES_INITIALSColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));
                    resourceFilter.Fields.Add(new PSLibrary.Filter.Field(resourceDs.Resources.TableName, resourceDs.Resources.WRES_ACCOUNTColumn.ColumnName, PSLibrary.Filter.SortOrderTypeEnum.None));

                    String filterXml = resourceFilter.GetXml();

                    resourceDs = resource.ReadResources(filterXml, false);

    Hope this helps.

    Regards,
    George

    Thursday, March 3, 2011 11:25 AM
  • Thanks George,
    I was already able to build an xml filter using PSLib.Filter.Field objects as you wrote in your example.
    Anyway thanks to your last suggestion I resolved my issue in this way:

    PSLib.Filter resourceFilter = new PSLib.Filter();
    //resourceFilter.FilterTableName = dsResource.ResourceCustomFields.TableName;
    resourceFilter.FilterTableName = dsResource.Resources.TableName;

    resourceFilter.Fields.Add(new PSLib.Filter.Field(dsResource.Resources.TableName, dsResource.Resources.RES_UIDColumn.ColumnName, PSLib.Filter.SortOrderTypeEnum.None));
    resourceFilter.Fields.Add(new PSLib.Filter.CustomField(dsResource.ResourceCustomFields.TableName, new Guid("1945c571-5405-490a-b84f-af047c34d0ff"), PSLib.Filter.PropertyTypeEnum.TextValue));

    Notice that if I set the FilterTableName property with "ResourceCustomFields" table name PSI comes out with a "ResourceFilterInvalid" error (description is: "Join _Resources_ is missing from provided joins").
    Conversely if I use the "Resources" table name PSI works properly (somehow strange to me).

    Then I filtered my resources with OR logical operators in the criteria:

    Guid[] guidElementi = new Guid[] { new Guid("46f296e3-2b34-4900-836f-10cab51098d3"),
                                       new Guid("e5c6aef7-08a6-4a3c-aafc-20369822dcd0"),
                                       new Guid("246877a3-1933-4cd6-8c01-24abe13377fe"),
                                       new Guid("5c3428e3-5bd4-45ee-a77f-2f8463b653d8")};

    PSLib.Filter.IOperator[] fos = new PSLib.Filter.IOperator[guidElementi.Length];
    for (int i = 0; i < guidElementi.Length; i++) {
      fos[i] = new PSLib.Filter.FieldOperator(PSLib.Filter.FieldOperationType.Equal, sCampoChiaveElem, guidElementi[i]);
    }
    PSLib.Filter.LogicalOperator lo = new PSLib.Filter.LogicalOperator(PSLib.Filter.LogicalOperationType.Or, fos);
    resourceFilter.Criteria = lo;

    string resourceAssignmentFilterXml = resourceFilter.GetXml();
    dsResource = AdminUtils.svcResource.ReadResources(resourceAssignmentFilterXml, false);

    Thank you very much for your kind support.

    Daniele

    • Marked as answer by geo_d Friday, March 4, 2011 9:14 AM
    Thursday, March 3, 2011 5:53 PM
  • Glad to hear you resolved the issue!
    Friday, March 4, 2011 9:13 AM