Common Custom tasks
Common_CustomTasks_CSharp\ScriptTask_CSharp\SimpleScriptTask.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.
// 

namespace ESRI.ADF.Samples.CustomTasks
{
    [System.Web.UI.ToolboxData(@"<{0}:SimpleScriptTask runat=""server"" BackColor=""White""
        BorderColor=""LightSteelBlue"" BorderStyle=""Outset"" BorderWidth=""1px"" Font-Names=""Verdana""
        Font-Size=""8pt"" ForeColor=""Black"" TitleBarColor=""WhiteSmoke"" TitleBarHeight=""20px""
        TitleBarSeparatorLine=""True"" Transparency=""35"" Width=""130px"">
        </{0}:SimpleScriptTask>")]
    public class SimpleScriptTask : ESRI.ADF.Samples.CustomTasks.ScriptTask
    {
        #region Instance Variable Declarations

        // Stores the name of the ArcGIS Server host machine to connect to
        private const string _hostName = "localhost";

        // TextBox for users to input a map service name.  The ClientMember attribute exposes this
        // property on the client-side task object.
        [ESRI.ADF.Samples.CustomTasks.ScriptTask.ClientMember]
        System.Web.UI.WebControls.TextBox _mapServiceTextBox;

        // Button to initiate layer retrieval
        [ESRI.ADF.Samples.CustomTasks.ScriptTask.ClientMember]
        private System.Web.UI.HtmlControls.HtmlInputButton _getLayersButton;
        
        // Div storing the task's activity indicator
        [ESRI.ADF.Samples.CustomTasks.ScriptTask.ClientMember]
        private System.Web.UI.HtmlControls.HtmlGenericControl _retrievingLayersDiv;

        // Label for reporting the status of the last layer retrieval operation
        [ESRI.ADF.Samples.CustomTasks.ScriptTask.ClientMember]
        private System.Web.UI.WebControls.Label _statusLabel;

        #endregion

        #region ASP.NET WebControl Life Cycle Event Overrides - CreateChildControls, Render

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            // Add map service textbox and get layers button
            CreateMapServiceSection();

            // Add status label
            CreateLabelSection();
        }

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            base.Render(writer);

            // Create JavaScript to initialize handlers for the client-side task.  Note this must be
            // done after base.Render is called, as the client-side task will otherwise not be 
            // instantiated yet.
            string initializeTaskJavaScript = @"
                // Adds handlers to the client-side task
                function initializeScriptTask() {{
                    // Get the task
                    var task = $find('{0}');

                    // Add a handler for the Get Layer button's onclick event
                    $addHandler(task.get__getLayersButton(), 'click', onGetLayersClick);
            
                    // Add a handler for the onGetLayerNamesComplete event.  Note that this
                    // event is available because the GetLayerNames server-side method was
                    // exposed on the client via the ClientMember attribute.  This event 
                    // fires after a client-side call to GetLayerNames has executed on the
                    // server and results have been returned to the client.                     
                    task.add_onGetLayerNamesComplete(updateRetrievalStatus);
                }}

                // Fires when the Get Layers button is clicked
                function onGetLayersClick() {{
                    // Get the task
                    var task = this.get_task();

                    // Hide the button and show the activity indicator
                    task.get__getLayersButton().style.display = 'none';
                    task.get__retrievingLayersDiv().style.display = 'inline';
                
                    // Call the server-side GetLayerNames function, which has been exposed
                    // to the client because the ClientMember attribute was added to 
                    // GetLayerNames' declaration
                    task.GetLayerNames(task.get__mapServiceTextBox().value);
                }}  
                
                // Fires after GetLayerNames has been called and results have been returned
                // to the client
                function updateRetrievalStatus(status) {{     
                    // Display the passed-in value on the status label
                    this.get__statusLabel().style.display = 'inline';
                    this.get__statusLabel().innerHTML = status;

                    // Hide the activity indicator and show the Get Layers button
                    this.get__getLayersButton().style.display = 'inline';
                    this.get__retrievingLayersDiv().style.display = 'none';
                }}                
                
                // Add the initialization function as a handler for the AJAX init event
                Sys.Application.add_init(initializeScriptTask);";

            // Substitute the task's client ID into the script and register it on the client
            initializeTaskJavaScript = string.Format(initializeTaskJavaScript, this.ClientID);
            System.Web.UI.ScriptManager.RegisterStartupScript(this, this.GetType(),
                this.ClientID + "_initializeTask", initializeTaskJavaScript, true);
        }

        #endregion

        #region Public Methods - GetLayerNames

        // Retrieves the layers belonging to the map service specified.  The inclusion of the 
        // ClientMember attribute means this method can be called from the client-side task.
        [ESRI.ADF.Samples.CustomTasks.ScriptTask.ClientMember]
        public string GetLayerNames(string mapServiceName)
        {
            // Holds the text to display on the status label
            string retrievalStatus;

            try
            {
                // Connect to the map service
                string mapServiceUrl = string.Format("http://{0}/arcgis/services/{1}/MapServer",
                    _hostName, mapServiceName);
                ESRI.ArcGIS.ADF.ArcGISServer.MapServerProxy mapServerProxy =
                    new ESRI.ArcGIS.ADF.ArcGISServer.MapServerProxy(mapServiceUrl);

                // Get the map service's info
                ESRI.ArcGIS.ADF.ArcGISServer.MapServerInfo mapServerInfo =
                    mapServerProxy.GetServerInfo(mapServerProxy.GetDefaultMapName());

                // Iterate through the map service's layer info objects, adding the name of each
                // layer to a string
                string layerList = "";
                foreach (ESRI.ArcGIS.ADF.ArcGISServer.MapLayerInfo mapLayerInfo in
                mapServerInfo.MapLayerInfos)
                    layerList += mapLayerInfo.Name + "<br />";

                // String to use as the heading of the task result
                string taskResultHeading = string.Format("Layers in the {0} map service", mapServiceName);

                // Create a simple task result with the heading and list of layers
                ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult simpleTaskResult =
                    new ESRI.ArcGIS.ADF.Web.UI.WebControls.SimpleTaskResult(taskResultHeading, layerList);

                // Get the task's TaskResultsContainer
                ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults taskResultsContainer =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl(this.TaskResultsContainers[0].Name,
                    this.Page) as ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults;

                // Display the simple task result
                taskResultsContainer.DisplayResults(null, null, null, simpleTaskResult);

                // Copy the task results callback results to the task so they are processed on the client.
                // Without this, the task result wouldn't show up on the client.
                this.CallbackResults.CopyFrom(taskResultsContainer.CallbackResults);

                // Create a message indicating the operation was successful
                retrievalStatus = string.Format("Layers for <b>{0}</b> retrieved successfully", mapServiceName);
            }
            catch (System.Exception exception)
            {
                // Create a message indicating the operation was unsuccessful.  Include the exception's message.
                retrievalStatus = string.Format("Error retrieving layers for <b>{0}</b>:<br />{1}",
                    mapServiceName, exception.Message);
            }

            // Return the status.  For methods declared with the ClientMember attribute, the value returned is
            // passed to the handlers of the client-side on<methodName>Complete event.
            return retrievalStatus;
        }

        #endregion

        #region Instance Methods for UI creation

        // Creates the map service label, map service textbox, Get Layers button, and activity indicator
        private void CreateMapServiceSection()
        {
            // Table for managing placment of the controls
            System.Web.UI.WebControls.Table table = new System.Web.UI.WebControls.Table();
            this.Controls.Add(table);

            // Table row for managing placement of the controls
            System.Web.UI.WebControls.TableRow tableRow = new System.Web.UI.WebControls.TableRow();
            table.Rows.Add(tableRow);

            // Table cell to hold the map service label
            System.Web.UI.WebControls.TableCell tableCell = new System.Web.UI.WebControls.TableCell();
            tableRow.Cells.Add(tableCell);

            // Initialize the map service label and place it inside a table cell
            System.Web.UI.WebControls.Label mapServiceLabel = new System.Web.UI.WebControls.Label();
            mapServiceLabel.Text = "Map Service:";
            mapServiceLabel.Style[System.Web.UI.HtmlTextWriterStyle.WhiteSpace] = "nowrap";
            tableCell.Controls.Add(mapServiceLabel);

            // Table cell to hold the map service textbox
            tableCell = new System.Web.UI.WebControls.TableCell();
            tableRow.Cells.Add(tableCell);

            // Instantiate the map service textbox and add it to the cell
            _mapServiceTextBox = new System.Web.UI.WebControls.TextBox();
            tableCell.Controls.Add(_mapServiceTextBox);

            // Table cell to hold the Get Layers button and activity indicator
            tableCell = new System.Web.UI.WebControls.TableCell();
            tableCell.Style[System.Web.UI.HtmlTextWriterStyle.WhiteSpace] = "nowrap";
            tableRow.Cells.Add(tableCell);

            // Initialize the Get Layers button and add it to the cell
            _getLayersButton = new System.Web.UI.HtmlControls.HtmlInputButton();
            _getLayersButton.Value = "Get Layers";
            tableCell.Controls.Add(_getLayersButton);

            // Initialize a div to hold the activity indicator and add it to the cell.  Specify that the
            // div be hidden.
            _retrievingLayersDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
            _retrievingLayersDiv.Style[System.Web.UI.HtmlTextWriterStyle.Display] = "none";
            tableCell.Controls.Add(_retrievingLayersDiv);

            // Initialize an image with an activity indicator and add it to the div
            System.Web.UI.WebControls.Image retrievingLayersImage = new System.Web.UI.WebControls.Image();
            retrievingLayersImage.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(
                typeof(SimpleScriptTask), "ESRI.ADF.Samples.CustomTasks.images.activity_indicator.gif");
            _retrievingLayersDiv.Controls.Add(retrievingLayersImage);

            // Initialize a label to display along with the activity indicator image and add it to the div
            System.Web.UI.WebControls.Label retrievingLayersLabel = new System.Web.UI.WebControls.Label();
            retrievingLayersLabel.Text = "Retrieving Layers...";
            _retrievingLayersDiv.Controls.Add(retrievingLayersLabel);
        }

        // Creates the status label
        private void CreateLabelSection()
        {
            // Table for managing placement of the controls
            System.Web.UI.WebControls.Table table = new System.Web.UI.WebControls.Table();
            this.Controls.Add(table);

            // Table row for managing placement of the controls
            System.Web.UI.WebControls.TableRow tableRow = new System.Web.UI.WebControls.TableRow();
            table.Rows.Add(tableRow);

            // Table cell to hold the status label
            System.Web.UI.WebControls.TableCell tableCell = new System.Web.UI.WebControls.TableCell();
            tableRow.Cells.Add(tableCell);

            // Initialize the status label and add it to the cell
            _statusLabel = new System.Web.UI.WebControls.Label();
            _statusLabel.Style[System.Web.UI.HtmlTextWriterStyle.Display] = "none";
            tableCell.Controls.Add(_statusLabel);
        }

        #endregion
    }
}