This document is archived and information here might be outdated.  Recommended version.


Accessing map services with server object extensions (ArcObjects .NET 10.4 SDK)

Accessing map services with server object extensions


Summary
When using map services with server object extensions (SOEs), you should use the MapServer-related classes. Also, you can use IMapServerDataAccess to access the source data for the layers in your map. From there you can do many things to work with the data directly.

In this topic


About accessing map services

Map services use a different drawing engine than ArcMap. This drawing engine is optimized for draw speed in a server environment. However, this also means that map services do not support full ArcObjects access from the Carto library. When working with map services, you cannot use any ArcObjects directly related to the ArcMap documents (MXDs). This includes IMap, ILayer, IFeatureLayer, and any items relating to page layouts, text elements, and so forth.
You can still do quite a few things when you use a map service with your SOE. The following information summarizes what is available.

What you can do

The Carto library contains a MapServer class that represents the map service. There are a number of supporting classes and interfaces surrounding MapServer that give you information such as the layer names, whether the service has a cache or not, and how queries should be performed with the service. Examples include MapServer, MapLayerInfos, and MapDescription.
On the MapServer page of the .NET Carto Object Model Diagram (OMD), you can see these supported classes and interfaces. Avoid using other classes in the Carto library.
Classes in other libraries such as ESRI.ArcGIS.Geometry and ESRI.ArcGIS.Geodatabase are always acceptable for use with SOEs.

Getting to the source data

The MapServer class implements the interface IMapServerDataAccess, which allows you to access the data sources of the layers in your map. Using the GetDataSource method on this interface, you can access the IFeatureClass, IRaster, or ITable interface of the underlying data.
The typical pattern is to use the MapServer-related classes and interfaces to discover the layer names and indices in your map service, then use IMapServerDataAccess to get to the data beneath. Once you obtain the source data, you can do many things with it using ArcObjects, such as opening feature cursors or topological operators. You are safe as long as you avoid the previously mentioned MXD-specific classes from the Carto library. The following code example shows getting the source feature class for a map layer named "States".
[C#]
string mapLayerToFind="States";
//Access the map service and its layer infos.
ESRI.ArcGIS.Carto.IMapServer3 mapServer=(ESRI.ArcGIS.Carto.IMapServer3)
    serverObjectHelper.ServerObject;
string mapName=mapServer.DefaultMapName;
IMapLayerInfos layerInfos=mapServer.GetServerInfo(mapName).MapLayerInfos;
IMapLayerInfo layerInfo;

// Find the index of the layer of interest.
int c=layerInfos.Count;
int layerIndex=0;
for (int i=0; i < c; i++)
{
    layerInfo=layerInfos.get_Element(i);
    if (layerInfo.Name == mapLayerToFind)
    {
        layerIndex=i;
        break;
    }
}

// Access the source feature class.
IMapServerDataAccess dataAccess=(IMapServerDataAccess)mapServer;
IFeatureClass fc=(IFeatureClass)dataAccess.GetDataSource(mapName, layerIndex);
[VB.NET]
Dim mapLayerToFind As String="States"
'Access the map service and its layer infos.
Dim mapServer As ESRI.ArcGIS.Carto.IMapServer3=DirectCast(serverObjectHelper.ServerObject, ESRI.ArcGIS.Carto.IMapServer3)
Dim mapName As String=mapServer.DefaultMapName
Dim layerInfos As IMapLayerInfos=mapServer.GetServerInfo(mapName).MapLayerInfos
Dim layerInfo As IMapLayerInfo
' Find the index of the layer of interest.
Dim c As Integer=layerInfos.Count
Dim layerIndex As Integer=0
For i As Integer=0 To c - 1
    layerInfo=layerInfos.get_Element(i)
    If layerInfo.Name=mapLayerToFind Then
        layerIndex=i
        Exit For
    End If
Next

' Access the source feature class.
Dim dataAccess As IMapServerDataAccess=DirectCast(mapServer, IMapServerDataAccess)
Dim fc As IFeatureClass=DirectCast(dataAccess.GetDataSource(mapName, layerIndex), IFeatureClass)
The previous code example gets all the layer information for the map service. IMapLayerInfos and IMapLayerInfo are legal to use because they do not require access to a map document (they just help you get information that the service exposes).
The code example then iterates through the layer infos until it finds the index of the layer named “States”. That index is then passed into IMapServerDataAccess.GetDataSource(). At this point you’ve reached your goal of accessing the source data interface IFeatureClass.
For brevity, the previous code example contains no error handling; but you might want to add a check that IMapLayerInfo.Type is equal to “Feature Layer” before you cast the result to IFeatureClass.