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