Server spatial query server object extension
SpatialQuerySOE_WebSite_CSharp\App_Code\VegTool.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

/// <summary>
/// Defines logic that executes when the user clicks the map with the Vegetation Summary Proximity Search Tool. 
/// Uses the Spatial Query custom server object extension to retrieve buffer geometry and summary statistics for a 
/// user-specified distance around the click point.
/// </summary>
public class VegTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction 
{
    #region IMapServerToolAction Members

    public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs)
    {
        // Get the map control that was clicked
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = toolEventArgs.Control as ESRI.ArcGIS.ADF.Web.UI.WebControls.Map;
        
        // Get the page containing the map control
        System.Web.UI.Page page = adfMap.Page;

        // Get the request parameters
        System.Collections.Specialized.NameValueCollection requestParameters = null;       
        if (System.Web.UI.ScriptManager.GetCurrent(page) == null)
            requestParameters = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(
                page.Request.Params["__CALLBACKPARAM"]);
        else
            requestParameters = page.Request.Params;

        // Get the search distance
        double searchDistance;
        if (!System.Double.TryParse(requestParameters["SearchDistanceTextBox"], out searchDistance))
            searchDistance = 10000;

        // Get the value of the Show Results checkbox
        bool showSummaryStats;
        if (!bool.TryParse(requestParameters["ShowResultsCheckBox"], out showSummaryStats))
            showSummaryStats = false;

        // Get MapFunctionality and MapResource for the Vegetation Layers resource item
        ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality = 
            adfMap.GetFunctionality("Vegetation Layers") as ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality;
        ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal agsMapResourceLocal = 
            (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal) agsMapFunctionality.MapResource;

        // Get the server context
        ESRI.ArcGIS.Server.IServerContext serverContext = agsMapResourceLocal.ServerContextInfo.ServerContext;

        // Get the click point as an ArcObjects point
        ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = toolEventArgs as
            ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs;
        ESRI.ArcGIS.Geometry.IPoint clickPoint = (ESRI.ArcGIS.Geometry.IPoint)serverContext.CreateObject("esriGeometry.Point");
        clickPoint.X = mapPointEventArgs.MapPoint.X;
        clickPoint.Y = mapPointEventArgs.MapPoint.Y;

        // Get the Spatial Query server object extension
        ESRI.ArcGIS.Carto.IMapServer mapServer = agsMapResourceLocal.MapServer;
        ESRI.ArcGIS.Server.IServerObjectExtensionManager serverObjectExtensionManager = mapServer as 
            ESRI.ArcGIS.Server.IServerObjectExtensionManager;
        ESRI.ArcGIS.Server.IServerObjectExtension serverObjectExtension = 
            serverObjectExtensionManager.FindExtensionByTypeName("SpatialQuerySOE");
        SpatialQuerySOE.Interfaces.IExtension spatialQuerySOE = serverObjectExtension as SpatialQuerySOE.Interfaces.IExtension;

        // Execute the SOE's logic
        SpatialQuerySOE.Interfaces.IResults spatialQueryResults = spatialQuerySOE.QueryPoint(clickPoint, searchDistance);

        // Get the results graphics
        ESRI.ArcGIS.ADF.ArcGISServer.GraphicElement[] resultsGraphics = ESRI.ArcGIS.ADF.ArcGISServer.Converter.ComObjectToValueObject(
            spatialQueryResults.ResultsGraphics, serverContext, typeof(ESRI.ArcGIS.ADF.ArcGISServer.GraphicElement[])) as
            ESRI.ArcGIS.ADF.ArcGISServer.GraphicElement[];

        // Create a symbol for the graphics' outlines
        ESRI.ArcGIS.ADF.ArcGISServer.RgbColor rgbColor = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor();
        rgbColor.Red = 155;
        rgbColor.Green = 0;
        rgbColor.Blue = 0;
        rgbColor.AlphaValue = 255;
        
        ESRI.ArcGIS.ADF.ArcGISServer.SimpleLineSymbol simpleLineSymbol = new ESRI.ArcGIS.ADF.ArcGISServer.SimpleLineSymbol();
        simpleLineSymbol.Style = ESRI.ArcGIS.ADF.ArcGISServer.esriSimpleLineStyle.esriSLSSolid;
        simpleLineSymbol.Color = rgbColor;
        simpleLineSymbol.Width = 0.2;

        // Apply the symbol to the graphics
        foreach (ESRI.ArcGIS.ADF.ArcGISServer.PolygonElement polygonElement in resultsGraphics)
        {
            ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol simpleFillSymbol = polygonElement.Symbol as
                ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol;
            simpleFillSymbol.Outline = simpleLineSymbol;
        }

        // Add the graphics to the map
        agsMapFunctionality.MapDescription.CustomGraphics = resultsGraphics;

        // Get the grid view for displaying summary stats
        System.Web.UI.WebControls.GridView summaryStatsGridView = adfMap.Page.FindControl("GridView1") as System.Web.UI.WebControls.GridView;
        
        // Update the summary stats grid view if the stats are to be shown
        if (showSummaryStats)
        {
            // Get the summary statistics as a value object record set
            ESRI.ArcGIS.ADF.ArcGISServer.RecordSet summaryStatsRecordSet = 
                ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ComObjectToValueObject(
                spatialQueryResults.SummaryStatistics, serverContext, typeof(ESRI.ArcGIS.ADF.ArcGISServer.RecordSet)) as
                ESRI.ArcGIS.ADF.ArcGISServer.RecordSet;

            // Convert the record set to a DataTable
            System.Data.DataTable summaryStatsDataTable = 
                ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToDataTable(summaryStatsRecordSet);

            if (summaryStatsDataTable.Rows.Count > 0)
            {
                // Bind the summary stats to the grid view
                summaryStatsGridView.DataSource = summaryStatsDataTable;
                summaryStatsGridView.DataBind();

                // Get the grid view's HTML
                System.IO.StringWriter stringWriter = new System.IO.StringWriter();
                System.Web.UI.HtmlTextWriter htmlTextWriter = new System.Web.UI.HtmlTextWriter(stringWriter);
                summaryStatsGridView.RenderControl(htmlTextWriter);
                htmlTextWriter.Flush();
                string gridViewHtml = stringWriter.ToString();

                // Create a callback result that will update the summary stats grid view
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult updateStatsTableCallbackResult =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent("summaryStatsDiv", gridViewHtml);
                adfMap.CallbackResults.Add(updateStatsTableCallbackResult);
            }
            else
            {
                showSummaryStats = false;
            }
        }

        // Create a callback result that will update the visibility of the summary stats div and busy indicator via JavaScript
        string statsDivVisibility = showSummaryStats ? "" : "none";
        string setElementVisibilityScript = @"
            var summaryStatsDiv = $get('summaryStatsDiv');
            summaryStatsDiv.style.display = '{0}';

            var busyIndicator = $get('busyIndicator');
            busyIndicator.style.display = 'none';";
        setElementVisibilityScript = string.Format(setElementVisibilityScript, statsDivVisibility);
        ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult setStatsDivVisibilityCallbackResult =
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(setElementVisibilityScript);
        adfMap.CallbackResults.Add(setStatsDivVisibilityCallbackResult);

        adfMap.RefreshResource(agsMapResourceLocal.Name);
    }

    #endregion
}