[GIS] In C# ArcObjects, how to get layer field names from ArcGIS Server layer

add-inarcgis-serverarcmaparcobjectsc

I'm creating an add-in to ArcMap using C#. I need to get all the fields of every layer.

Code below works to get the fields when the layer is added via a shapefile. However, I can't get the fields when a layer is added from an ArcGIS Server URL (Map service or Feature service), via Catalog -> GIS Servers -> Add ArcGIS Server. The cast of ILayer to ILayerFields comes back null every time. I know the fields exist in the layer, as they show up with an Identify operation.

Is there a different method I should use to get fields from the ArcGIS Server layers? Or is it even possible to get the fields from Server layers?

private void AddLayerNames(string aPath, ILayer aParent, Dictionary<string, List<string>> aFieldNames)
    {
        if (aPath == string.Empty)
        {
            aPath = aParent.Name;
        }
        else
        {
            aPath = aPath + '/' + aParent.Name;
        }

        var lCompositeLayer = aParent as ICompositeLayer;
        if (lCompositeLayer == null)
        {
            if (!aFieldNames.ContainsKey(aPath))
            {
                aFieldNames.Add(aPath, new List<string>());
                var lFields = aParent as ILayerFields;
                if (lFields != null)
                {
                    for (int lFieldIndex = 0; lFieldIndex < lFields.FieldCount; lFieldIndex++)
                    {
                        var lFieldName = lFields.Field[lFieldIndex].Name;
                        aFieldNames[aPath].Add(lFieldName);
                    }
                }

            }
        }
        else
        {
            for (int lLayerIndex = 0; lLayerIndex < lCompositeLayer.Count; lLayerIndex++)
            {
                AddLayerNames(aPath, lCompositeLayer.Layer[lLayerIndex], aFieldNames);
            }
        }
    }

Best Answer

The solution is to cast ILayerto MapServerQuerySublayer then to IFind, then access IFind.FindFields.

Final code:

private void AddLayerNames(string aPath, ILayer aParent, Dictionary<string, List<string>> aLayerFieldNames)
{
    if (aPath == string.Empty)
    {
        aPath = aParent.Name;
    }
    else
    {
        aPath = aPath + '/' + aParent.Name;
    }

    var lCompositeLayer = aParent as ICompositeLayer;
    if (lCompositeLayer == null)
    {
        if (!aLayerFieldNames.ContainsKey(aPath))
        {
            // Add Layer Name
            aLayerFieldNames.Add(aPath, new List<string>());

            // Layer from local file
            var lFields = aParent as ILayerFields;
            if (lFields != null)
            {
                // Add Field Names
                for (int lFieldIndex = 0; lFieldIndex < lFields.FieldCount; lFieldIndex++)
                {
                    var lFieldName = lFields.Field[lFieldIndex].Name;
                    aLayerFieldNames[aPath].Add(lFieldName);
                }
            }
            // Layer from ArcGIS Server 
            else if (aParent is MapServerQuerySublayer)
            {
                var lQuery = aParent as MapServerQuerySublayer;
                var lFind = lQuery as IFind;
                if (lFind != null)
                {
                    var lFindFields = lFind.FindFields;
                    // Add Field Names
                    for (int lFieldIndex = 0; lFieldIndex < lFindFields.Length; lFieldIndex++)
                    {
                        var lFieldName = lFindFields[lFieldIndex];
                        aLayerFieldNames[aPath].Add(lFieldName);
                    }
                }
            }
        }
    }
    else
    {
        for (int lLayerIndex = 0; lLayerIndex < lCompositeLayer.Count; lLayerIndex++)
        {
            AddLayerNames(aPath, lCompositeLayer.Layer[lLayerIndex], aLayerFieldNames);
        }
    }
}
Related Question