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