ArcObjects Library Reference  

Configurator

About the Server spatial query server object extension Sample

[C#]

Configurator.cs

using System;
using System.Collections.Generic;
using System.Text;

namespace SpatialQuerySOE.Manager
{
    /// <summary>
    /// SpatialQuerySOE property configuration page for Manager.  Defines the appearance and behavior of the page.
    /// </summary>
    public class Configurator : ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator
    {
        #region Member variables
        
        // Controls to enable configuration of the SOE's layer and field
        private System.Web.UI.WebControls.DropDownList m_layersDropDown = new System.Web.UI.WebControls.DropDownList();
        private System.Web.UI.WebControls.DropDownList m_fieldsDropDown = new System.Web.UI.WebControls.DropDownList();

        // The SOE's current layer
        private string m_layer;

        // The SOE's current field
        private string m_field;

        // JSON string storing the names of the current service's layers and their fields
        private string m_jsonServiceLayersAndFields = "{}";
        
        #endregion

        #region IServerObjectExtensionConfigurator Members

        #region Properties - HtmlElementIds, SupportingJavaScript

        /// <summary>
        /// IDs of the controls that define SOE properties
        /// </summary>
        public List<string> HtmlElementIds
        {
            get { return new List<string>(new string[] { "layersDropDown", "fieldsDropDown" }); }
        }

        /// <summary>
        /// JavaScript to execute when the property page is loaded
        /// </summary>
        public string SupportingJavaScript
        {
            get
            {
                return string.Format(@"
                    // JSON object storing the names of the current service's layers and their fields
                    var layerFieldsMapping = {0};

                    // ExtensionConfigurator is a global JavaScript object defined by Manager and available to SOE property page
                    // implementations.  Here we use it to define the client logic to execute when a new layer is selected.
                    ExtensionConfigurator.OnLayerChanged = function(layersDropDown) {{
                        // Get the currently selected layer                           
                        var layerName = layersDropDown.options[layersDropDown.selectedIndex].value;
                        // Get the fields drop down and the number of items in it
                        var fieldsDropDown = document.getElementById('fieldsDropDown');  
                        var len = fieldsDropDown.options ? fieldsDropDown.options.length : 0;

                        // Remove all the drop down's items
                        for(var i=0; i < len; i++)
                            fieldsDropDown.remove(0);

                        // Get the fields for the currently selected layer and populate the fields drop down with them
                        var fieldsArray = layerFieldsMapping[layerName];
                        if(fieldsArray)
                        {{  
                            for(i=0; i < fieldsArray.length; i++)
                                fieldsDropDown.options.add(new Option(fieldsArray[i], fieldsArray[i]));

                            fieldsDropDown.options[0].selected = true;
                        }}
                    }}", m_jsonServiceLayersAndFields);
            }
        }

        #endregion

        #region Methods - LoadConfigurator, SaveProperties

        /// <summary>
        /// Called when the property page is loaded
        /// </summary>
        /// <param name="serverContext">server context for the service</param>
        /// <param name="ServerObjectProperties">properties of the server object (i.e. service)</param>
        /// <param name="ExtensionProperties">SOE properties for the current server object</param>
        /// <param name="InfoProperties">global SOE properties</param>
        /// <param name="isEnabled">whether the SOE is enabled on the current server object</param>
        /// <param name="servicesEndPoint">end point for server's web services </param>
        /// <param name="serviceName">name of the server object</param>
        /// <returns>An HTML string that defines the property page's UI</returns>
        public string LoadConfigurator(ESRI.ArcGIS.Server.IServerContext serverContext,
                        System.Collections.Specialized.NameValueCollection ServerObjectProperties,
                        System.Collections.Specialized.NameValueCollection ExtensionProperties,
                        System.Collections.Specialized.NameValueCollection InfoProperties,
                        bool isEnabled, string servicesEndPoint, string serviceName)
        {
            // Just return a message if the SOE is not enabled on the current service
            if (!isEnabled)
                return ("<span>No Properties to configure</span>");

            // Initialize member variables holding the SOE's properties
            if (!string.IsNullOrEmpty(ExtensionProperties["LayerName"]))
                m_layer = ExtensionProperties["LayerName"];
            if (!string.IsNullOrEmpty(ExtensionProperties["FieldName"]))
                m_field = ExtensionProperties["FieldName"];


            //Container div and table          
            System.Web.UI.HtmlControls.HtmlGenericControl propertiesDiv =
                new System.Web.UI.HtmlControls.HtmlGenericControl("propertiesDiv");
            propertiesDiv.Style[System.Web.UI.HtmlTextWriterStyle.Padding] = "10px";

            System.Web.UI.HtmlControls.HtmlTable table = new System.Web.UI.HtmlControls.HtmlTable();
            table.CellPadding = table.CellSpacing = 4;
            propertiesDiv.Controls.Add(table);


            // Header row
            System.Web.UI.HtmlControls.HtmlTableRow row = new System.Web.UI.HtmlControls.HtmlTableRow();
            table.Rows.Add(row);

            System.Web.UI.HtmlControls.HtmlTableCell cell = new System.Web.UI.HtmlControls.HtmlTableCell();
            row.Cells.Add(cell);
            cell.ColSpan = 2;

            System.Web.UI.WebControls.Label lbl = new System.Web.UI.WebControls.Label();
            lbl.Text = "Choose the layer and field.";
            cell.Controls.Add(lbl);


            // Layer drop-down row
            row = new System.Web.UI.HtmlControls.HtmlTableRow();
            table.Rows.Add(row);

            cell = new System.Web.UI.HtmlControls.HtmlTableCell();
            row.Cells.Add(cell);

            lbl = new System.Web.UI.WebControls.Label();
            cell.Controls.Add(lbl);
            lbl.Text = "Layer:";

            cell = new System.Web.UI.HtmlControls.HtmlTableCell();
            row.Cells.Add(cell);
            cell.Controls.Add(m_layersDropDown);
            m_layersDropDown.ID = "layersDropDown";

            // Wire the OnLayerChanged JavaScript function (defined in SupportingJavaScript) to fire when a new layer is selected
            m_layersDropDown.Attributes["onchange"] = "ExtensionConfigurator.OnLayerChanged(this);";


            // Fields drop-down row
            row = new System.Web.UI.HtmlControls.HtmlTableRow();
            table.Rows.Add(row);

            cell = new System.Web.UI.HtmlControls.HtmlTableCell();
            row.Cells.Add(cell);

            lbl = new System.Web.UI.WebControls.Label();
            cell.Controls.Add(lbl);
            lbl.Text = "Fields:";

            cell = new System.Web.UI.HtmlControls.HtmlTableCell();
            row.Cells.Add(cell);
            cell.Controls.Add(m_fieldsDropDown);
            m_fieldsDropDown.ID = "fieldsDropDown";



            // Get the path of the underlying map document and use it to populate the properties drop-downs
            string fileName = ServerObjectProperties["FilePath"];
            populateDropDowns(serverContext, fileName);


            // Render and return the HTML for the container div
            System.IO.StringWriter stringWriter = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter htmlWriter = new System.Web.UI.HtmlTextWriter(stringWriter);
            propertiesDiv.RenderControl(htmlWriter);
            string html = stringWriter.ToString();
            stringWriter.Close();
            return html;
        }

        /// <summary>
        /// Persists the server object extension's properties
        /// </summary>
        /// <param name="serverContext">the server context of the service</param>
        /// <param name="Request">values of the controls specified in HtmlElementIds</param>
        /// <param name="isEnabled">whether the extension is enabled on the current server object</param>
        /// <param name="ExtensionProperties">collection of server object properties to save</param>
        /// <param name="InfoProperties">collection of global extension properties to save</param>
        public void SaveProperties(ESRI.ArcGIS.Server.IServerContext serverContext,
            System.Collections.Specialized.NameValueCollection Request, bool isEnabled,
            out System.Collections.Specialized.NameValueCollection ExtensionProperties,
            out System.Collections.Specialized.NameValueCollection InfoProperties)
        {
            // Instantiate the properties collection and define the LayerName and FieldName properties
            ExtensionProperties = new System.Collections.Specialized.NameValueCollection();

            string layerName = Request["layersDropDown"];
            if (!string.IsNullOrEmpty(layerName))
                ExtensionProperties.Add("LayerName", layerName);

            string fieldName = Request["fieldsDropDown"];
            if (!string.IsNullOrEmpty(fieldName))
                ExtensionProperties.Add("FieldName", fieldName);

            InfoProperties = new System.Collections.Specialized.NameValueCollection();
        }

        #endregion

        #endregion

        // Retrieves the current service's layers and fields and populates the property page UI with them
        private void populateDropDowns(ESRI.ArcGIS.Server.IServerContext serverContext, string mapDocPath)
        {
            ESRI.ArcGIS.Carto.IMapDocument mapDoc = null;
            ESRI.ArcGIS.Carto.IMap map = null;
            try
            {
                // Get the map underlying the current service
                mapDoc = (ESRI.ArcGIS.Carto.IMapDocument)serverContext.CreateObject("esriCarto.MapDocument");
                mapDoc.Open(mapDocPath, null);
                map = mapDoc.get_Map(0);

                // Get IGeoFeatureLayers from the map
                ESRI.ArcGIS.esriSystem.UID id = (ESRI.ArcGIS.esriSystem.UID)serverContext.CreateObject("esriSystem.UID");
                id.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}";
                ESRI.ArcGIS.Carto.IEnumLayer enumLayer = map.get_Layers(id, true);

                // Loop through each layer and the fields for that layer.  For each simple polygon layer, add its name and 
                // a list containing the names of all its fields to the dictionary.
                ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)enumLayer.Next();
                Dictionary<string, List<string>> layersAndFieldsDictionary = new Dictionary<string, List<string>>();
                bool addFields = false;
                while (featureLayer != null)
                {
                    List<string> fieldsList = new List<string>();

                    // Check whether the current layer is a simple polygon layer
                    if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon
                           && featureLayer.FeatureClass.FeatureType == ESRI.ArcGIS.Geodatabase.esriFeatureType.esriFTSimple)
                    {
                        // Add the layer to the layers drop-down
                        m_layersDropDown.Items.Add(featureLayer.Name);

                        // Check whether the fields drop-down should be initialized with fields from the current loop layer
                        if (featureLayer.Name == m_layer || (m_layer == null && m_layersDropDown.Items.Count == 1))
                            addFields = true;

                        // Add each field to the fields list
                        ESRI.ArcGIS.Geodatabase.IFields fields = featureLayer.FeatureClass.Fields;
                        for (int i = 0; i < fields.FieldCount; i++)
                        {
                            ESRI.ArcGIS.Geodatabase.IField field = fields.get_Field(i);
                            fieldsList.Add(field.Name);

                            // If the current loop layer is the first, add its fields to the fields drop-down
                            if (addFields)
                                m_fieldsDropDown.Items.Add(field.Name);
                        }

                        addFields = false;

                        // Add the layer name and its fields to the dictionary
                        layersAndFieldsDictionary.Add(featureLayer.Name, fieldsList);
                    }

                    featureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)enumLayer.Next();
                }

                // Serialize the dictionary containing the layer and field names to JSON
                System.Web.Script.Serialization.JavaScriptSerializer serializer =
                    new System.Web.Script.Serialization.JavaScriptSerializer();
                m_jsonServiceLayersAndFields = serializer.Serialize(layersAndFieldsDictionary);

                // If a layer is defined for the extension, select it in the layers drop-down.
                if (m_layer != null)
                    m_layersDropDown.SelectedValue = m_layer;

                // If a field is defined for the extension, select it in the fields drop-down.
                if (m_field != null)
                    m_fieldsDropDown.SelectedValue = m_field;
            }
            catch { }
            finally
            {
                // Close the service's map document
                if (mapDoc != null)
                    mapDoc.Close();
                map = null;
            }
        }
    }
}

[Visual Basic .NET]

Configurator.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text

Namespace SpatialQuerySOE.Manager_VBNet
  ''' <summary>
  ''' SpatialQuerySOE property configuration page for Manager.  Defines the appearance and behavior of the page.
  ''' </summary>
  Public Class Configurator
    Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator

#Region "Member variables"

    ' Controls to enable configuration of the SOE's layer and field
    Private m_layersDropDown As New System.Web.UI.WebControls.DropDownList()
    Private m_fieldsDropDown As New System.Web.UI.WebControls.DropDownList()

    ' The SOE's current layer
    Private m_layer As String

    ' The SOE's current field
    Private m_field As String

    ' JSON string storing the names of the current service's layers and their fields
    Private m_jsonServiceLayersAndFields As String = "{}"

#End Region

#Region "IServerObjectExtensionConfigurator Members"

#Region "Properties - HtmlElementIds, SupportingJavaScript"

    ''' <summary>
    ''' IDs of the controls that define SOE properties
    ''' </summary>
    'Public ReadOnly Property HtmlElementIds() As List(Of String)
    '  Get
    '    Return New List(Of String)(New String() {"layersDropDown", "fieldsDropDown"})
    '  End Get
    'End Property
    Public ReadOnly Property HtmlElementIds1() As System.Collections.Generic.List(Of String) Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.HtmlElementIds
      Get
        Return New List(Of String)(New String() {"layersDropDown", "fieldsDropDown"})
      End Get
    End Property

    ''' <summary>
    ''' JavaScript to execute when the property page is loaded
    ''' </summary>
    Public ReadOnly Property SupportingJavaScript() As String Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.SupportingJavaScript
      Get
        Return String.Format("" & ControlChars.CrLf & "                    // JSON object storing the names of the current service's layers and their fields" & ControlChars.CrLf & "                    var layerFieldsMapping = {0};" & ControlChars.CrLf & ControlChars.CrLf & "                    // ExtensionConfigurator is a global JavaScript object defined by Manager and available to SOE property page" & ControlChars.CrLf & "                    // implementations.  Here we use it to define the client logic to execute when a new layer is selected." & ControlChars.CrLf & "                    ExtensionConfigurator.OnLayerChanged = function(layersDropDown) {{" & ControlChars.CrLf & "                        // Get the currently selected layer                           " & ControlChars.CrLf & "                        var layerName = layersDropDown.options[layersDropDown.selectedIndex].value;" & ControlChars.CrLf & "                        // Get the fields drop down and the number of items in it" & ControlChars.CrLf & "                        var fieldsDropDown = document.getElementById('fieldsDropDown');  " & ControlChars.CrLf & "                        var len = fieldsDropDown.options ? fieldsDropDown.options.length : 0;" & ControlChars.CrLf & ControlChars.CrLf & "                        // Remove all the drop down's items" & ControlChars.CrLf & "                        for(var i=0; i < len; i++)" & ControlChars.CrLf & "                            fieldsDropDown.remove(0);" & ControlChars.CrLf & ControlChars.CrLf & "                        // Get the fields for the currently selected layer and populate the fields drop down with them" & ControlChars.CrLf & "                        var fieldsArray = layerFieldsMapping[layerName];" & ControlChars.CrLf & "                        if(fieldsArray)" & ControlChars.CrLf & "                        {{  " & ControlChars.CrLf & "                            for(i=0; i < fieldsArray.length; i++)" & ControlChars.CrLf & "                                fieldsDropDown.options.add(new Option(fieldsArray[i], fieldsArray[i]));" & ControlChars.CrLf & ControlChars.CrLf & "                            fieldsDropDown.options[0].selected = true;" & ControlChars.CrLf & "                        }}" & ControlChars.CrLf & "                    }}", m_jsonServiceLayersAndFields)
      End Get
    End Property

#End Region

#Region "Methods - LoadConfigurator, SaveProperties"

    ''' <summary>
    ''' Called when the property page is loaded
    ''' </summary>
    ''' <param name="serverContext">server context for the service</param>
    ''' <param name="ServerObjectProperties">properties of the server object (i.e. service)</param>
    ''' <param name="ExtensionProperties">SOE properties for the current server object</param>
    ''' <param name="InfoProperties">global SOE properties</param>
    ''' <param name="isEnabled">whether the SOE is enabled on the current server object</param>
    ''' <param name="servicesEndPoint">end point for server's web services </param>
    ''' <param name="serviceName">name of the server object</param>
    ''' <returns>An HTML string that defines the property page's UI</returns>
    Public Function LoadConfigurator(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal ServerObjectProperties As System.Collections.Specialized.NameValueCollection, ByVal ExtensionProperties As System.Collections.Specialized.NameValueCollection, ByVal InfoProperties As System.Collections.Specialized.NameValueCollection, ByVal isEnabled As Boolean, ByVal servicesEndPoint As String, ByVal serviceName As String) As String Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.LoadConfigurator
      ' Just return a message if the SOE is not enabled on the current service
      If (Not isEnabled) Then
        Return ("<span>No Properties to configure</span>")
      End If

      ' Initialize member variables holding the SOE's properties
      If (Not String.IsNullOrEmpty(ExtensionProperties("LayerName"))) Then
        m_layer = ExtensionProperties("LayerName")
      End If
      If (Not String.IsNullOrEmpty(ExtensionProperties("FieldName"))) Then
        m_field = ExtensionProperties("FieldName")
      End If


      'Container div and table          
      Dim propertiesDiv As New System.Web.UI.HtmlControls.HtmlGenericControl("propertiesDiv")
      propertiesDiv.Style(System.Web.UI.HtmlTextWriterStyle.Padding) = "10px"

      Dim table As New System.Web.UI.HtmlControls.HtmlTable()
      table.CellSpacing = 4
      table.CellPadding = table.CellSpacing
      propertiesDiv.Controls.Add(table)


      ' Header row
      Dim row As New System.Web.UI.HtmlControls.HtmlTableRow()
      table.Rows.Add(row)

      Dim cell As New System.Web.UI.HtmlControls.HtmlTableCell()
      row.Cells.Add(cell)
      cell.ColSpan = 2

      Dim lbl As New System.Web.UI.WebControls.Label()
      lbl.Text = "Choose the layer and field."
      cell.Controls.Add(lbl)


      ' Layer drop-down row
      row = New System.Web.UI.HtmlControls.HtmlTableRow()
      table.Rows.Add(row)

      cell = New System.Web.UI.HtmlControls.HtmlTableCell()
      row.Cells.Add(cell)

      lbl = New System.Web.UI.WebControls.Label()
      cell.Controls.Add(lbl)
      lbl.Text = "Layer:"

      cell = New System.Web.UI.HtmlControls.HtmlTableCell()
      row.Cells.Add(cell)
      cell.Controls.Add(m_layersDropDown)
      m_layersDropDown.ID = "layersDropDown"

      ' Wire the OnLayerChanged JavaScript function (defined in SupportingJavaScript) to fire when a new layer is selected
      m_layersDropDown.Attributes("onchange") = "ExtensionConfigurator.OnLayerChanged(this);"


      ' Fields drop-down row
      row = New System.Web.UI.HtmlControls.HtmlTableRow()
      table.Rows.Add(row)

      cell = New System.Web.UI.HtmlControls.HtmlTableCell()
      row.Cells.Add(cell)

      lbl = New System.Web.UI.WebControls.Label()
      cell.Controls.Add(lbl)
      lbl.Text = "Fields:"

      cell = New System.Web.UI.HtmlControls.HtmlTableCell()
      row.Cells.Add(cell)
      cell.Controls.Add(m_fieldsDropDown)
      m_fieldsDropDown.ID = "fieldsDropDown"



      ' Get the path of the underlying map document and use it to populate the properties drop-downs
      Dim fileName As String = ServerObjectProperties("FilePath")
      populateDropDowns(serverContext, fileName)


      ' Render and return the HTML for the container div
      Dim stringWriter As New System.IO.StringWriter()
      Dim htmlWriter As New System.Web.UI.HtmlTextWriter(stringWriter)
      propertiesDiv.RenderControl(htmlWriter)
      Dim html As String = stringWriter.ToString()
      stringWriter.Close()
      Return html
    End Function

    ''' <summary>
    ''' Persists the server object extension's properties
    ''' </summary>
    ''' <param name="serverContext">the server context of the service</param>
    ''' <param name="Request">values of the controls specified in HtmlElementIds</param>
    ''' <param name="isEnabled">whether the extension is enabled on the current server object</param>
    ''' <param name="ExtensionProperties">collection of server object properties to save</param>
    ''' <param name="InfoProperties">collection of global extension properties to save</param>
    Public Sub SaveProperties(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal Request As System.Collections.Specialized.NameValueCollection, ByVal isEnabled As Boolean, <System.Runtime.InteropServices.Out()> ByRef ExtensionProperties As System.Collections.Specialized.NameValueCollection, <System.Runtime.InteropServices.Out()> ByRef InfoProperties As System.Collections.Specialized.NameValueCollection) Implements ESRI.ArcGIS.ServerManager.IServerObjectExtensionConfigurator.SaveProperties
      ' Instantiate the properties collection and define the LayerName and FieldName properties
      ExtensionProperties = New System.Collections.Specialized.NameValueCollection()

      Dim layerName As String = Request("layersDropDown")
      If (Not String.IsNullOrEmpty(layerName)) Then
        ExtensionProperties.Add("LayerName", layerName)
      End If

      Dim fieldName As String = Request("fieldsDropDown")
      If (Not String.IsNullOrEmpty(fieldName)) Then
        ExtensionProperties.Add("FieldName", fieldName)
      End If

      InfoProperties = New System.Collections.Specialized.NameValueCollection()
    End Sub

#End Region

#End Region

    ' Retrieves the current service's layers and fields and populates the property page UI with them
    Private Sub populateDropDowns(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal mapDocPath As String)
      Dim mapDoc As ESRI.ArcGIS.Carto.IMapDocument = Nothing
      Dim map As ESRI.ArcGIS.Carto.IMap = Nothing
      Try
        ' Get the map underlying the current service
        mapDoc = CType(serverContext.CreateObject("esriCarto.MapDocument"), ESRI.ArcGIS.Carto.IMapDocument)
        mapDoc.Open(mapDocPath, Nothing)
        map = mapDoc.Map(0)

        ' Get IGeoFeatureLayers from the map
        Dim id As ESRI.ArcGIS.esriSystem.UID = CType(serverContext.CreateObject("esriSystem.UID"), ESRI.ArcGIS.esriSystem.UID)
        id.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}"
        Dim enumLayer As ESRI.ArcGIS.Carto.IEnumLayer = map.Layers(id, True)

        ' Loop through each layer and the fields for that layer.  For each simple polygon layer, add its name and 
        ' a list containing the names of all its fields to the dictionary.
        Dim featureLayer As ESRI.ArcGIS.Carto.IFeatureLayer = CType(enumLayer.Next(), ESRI.ArcGIS.Carto.IFeatureLayer)
        Dim layersAndFieldsDictionary As New Dictionary(Of String, List(Of String))()
        Dim addFields As Boolean = False
        Do While featureLayer IsNot Nothing
          Dim fieldsList As New List(Of String)()

          ' Check whether the current layer is a simple polygon layer
          If featureLayer.FeatureClass.ShapeType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon AndAlso featureLayer.FeatureClass.FeatureType = ESRI.ArcGIS.Geodatabase.esriFeatureType.esriFTSimple Then
            ' Add the layer to the layers drop-down
            m_layersDropDown.Items.Add(featureLayer.Name)

            ' Check whether the fields drop-down should be initialized with fields from the current loop layer
            If featureLayer.Name = m_layer OrElse (m_layer Is Nothing AndAlso m_layersDropDown.Items.Count = 1) Then
              addFields = True
            End If

            ' Add each field to the fields list
            Dim fields As ESRI.ArcGIS.Geodatabase.IFields = featureLayer.FeatureClass.Fields
            For i As Integer = 0 To fields.FieldCount - 1
              Dim field As ESRI.ArcGIS.Geodatabase.IField = fields.Field(i)
              fieldsList.Add(field.Name)

              ' If the current loop layer is the first, add its fields to the fields drop-down
              If addFields Then
                m_fieldsDropDown.Items.Add(field.Name)
              End If
            Next i

            addFields = False

            ' Add the layer name and its fields to the dictionary
            layersAndFieldsDictionary.Add(featureLayer.Name, fieldsList)
          End If

          featureLayer = CType(enumLayer.Next(), ESRI.ArcGIS.Carto.IFeatureLayer)
        Loop

        ' Serialize the dictionary containing the layer and field names to JSON
        Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
        m_jsonServiceLayersAndFields = serializer.Serialize(layersAndFieldsDictionary)

        ' If a layer is defined for the extension, select it in the layers drop-down.
        If m_layer IsNot Nothing Then
          m_layersDropDown.SelectedValue = m_layer
        End If

        ' If a field is defined for the extension, select it in the fields drop-down.
        If m_field IsNot Nothing Then
          m_fieldsDropDown.SelectedValue = m_field
        End If
      Catch
      Finally
        ' Close the service's map document
        If mapDoc IsNot Nothing Then
          mapDoc.Close()
        End If
        map = Nothing
      End Try
    End Sub

    
  End Class
End Namespace