Common_Security_CSharp\App_Code\GetMapInformation.cs
// Copyright 2011 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 CustomComponents { public class GetMapInformation : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerCommandAction { #region IServerAction Members // Executes the action for the command. Gets information about the map's layers, packages that // information as a callback result, and passes the callback result back to the client for display. void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { // Get a reference to the map control to which the toolbar is buddied ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolbarItemInfo.BuddyControls[0]; try { // Get map/layer/field information via private method string mapInfoHtml = GetMapAndLayerInformation(adfMap); // Create a callback result that will replace the content of a div tag in the page with the // map information. The "HtmlGenericControl" paramter indicates the type of control to be // updated. The "divMapInfo" parameter indicates the ID of the control to be updated; // divMapInfo is a <div> element on the Default.aspx page. The "innercontent" parameter // specifies that the HTML content of the specified control is to be updated. The mapInfoHtml // parameter specifies the content with which we wish to update the specified control. ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult callbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent( "divMapInfo", mapInfoHtml); // add the callback result to the map's results so they will get // passed to the page adfMap.CallbackResults.Add(callbackResult); } catch (System.Exception exception) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = Utility.GetErrorCallback(exception); adfMap.CallbackResults.Add(errorCallbackResult); } } #endregion #region Instance Methods // Retrieves information about map services, layers, and fields for vector layers, and returns // this information as an HTML-formatted string. private string GetMapAndLayerInformation(ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap) { // make sure map resources are initialized if (!adfMap.InitializedFunctionalities) adfMap.InitializeFunctionalities(); // Intantiate a string builder object to use in creating the HTML markup. Initialize the string builder // with a title for the map information. System.Text.StringBuilder mapInfoStringBuilder = new System.Text.StringBuilder("<h2>Map Information:</h2>"); string[] fieldNames, layerIDs, layerNames; // loop through each map service foreach (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality in adfMap.GetFunctionalities()) { // Add the resource definition and name to the map information HTML ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = commonMapFunctionality.Resource; mapInfoStringBuilder.AppendFormat("<h3>Service: {0} ({1})</h3>", gisResource.ResourceDefinition, gisResource.Name); // Check whether the current resource supports ADF QueryFunctionality. We need this to access the // fields of vector layers if (gisResource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality))) { ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality commonQueryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisResource.CreateFunctionality( typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get layer IDs and names commonQueryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Iterate through the layer IDs for (int i = 0; i < layerIDs.Length; i++) { // Add the current layer's name to the map information HTML mapInfoStringBuilder.AppendFormat("<h4>Layer {0}</h4>Fields:<br/>", layerNames[i]); // Retrieve and iterate through the field names of the current layer fieldNames = commonQueryFunctionality.GetFields(null, layerIDs[i]); foreach (string fieldName in fieldNames) { // Add the name of the current field to the map information HTML mapInfoStringBuilder.AppendFormat("{0}<br/>", fieldName); } mapInfoStringBuilder.Append("<br>"); } } mapInfoStringBuilder.Append("<br>"); } return mapInfoStringBuilder.ToString(); } #endregion } public class Utility { // Constructs a callback result that will display an error message based on the passed-in // exception public static ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult GetErrorCallback( System.Exception exception) { // Create a callback result to display an error message string jsAlertErrorMessage = GetJavaScriptErrorString(exception); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult alertCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsAlertErrorMessage); return alertCallbackResult; } // Constructs JavaScript necessary to display an error message based on the passed-in exception. public static string GetJavaScriptErrorString(System.Exception exception) { // Get the website's configuration file System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration( System.Web.HttpContext.Current.Request.ApplicationPath); // Get the "compilation" section of the config file System.Web.Configuration.CompilationSection compilationSection = webConfig.GetSection("system.web/compilation") as System.Web.Configuration.CompilationSection; // If the config file's compilation section specifies debug mode, include // stack trace information in the error message. Otherwise, just return // the exception message. string errorMessage = null; if ((compilationSection != null) && (compilationSection.Debug)) { string stackTrace = exception.StackTrace.Replace("\\", "\\\\"); stackTrace = stackTrace.Replace("\n", "\\n"); stackTrace = stackTrace.Replace("\r", "\\r"); errorMessage = exception.Message + "\\n\\n" + stackTrace.Trim(); } else errorMessage = exception.Message; // Create a callback result to display an error message string jsAlertException = "alert('" + errorMessage + "')"; return jsAlertException; } // Gets the ID of the layer matching the input layer name. public static string GetLayerID(string layerName, ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mapFunctionality) { string layerID = string.Empty; // get layerIDs and names from the passed-in map functionality string[] layerIDs, layerNames; mapFunctionality.GetLayers(out layerIDs, out layerNames); // Loop through the layer names. If one of the names matches the passed-in layer name, // get that layer's ID and exit the loop. for (int i = 0; i < layerIDs.Length; i++) { if (layerNames[i] == layerName) { layerID = layerIDs[i]; break; } } return layerID; } // Finds the node having the passed-in name from among the input node or its child nodes. // Useful for searching a Toc with group layers. public static ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode FindNodeRecursive( ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode treeViewPlusNode, string nodeName) { // Check whether the text of the passed-in node matches the text sought. Return the node if so. if (treeViewPlusNode.Text == nodeName) return treeViewPlusNode; // Iterate through the passed-in node's child nodes, calling this function on each. foreach (ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode childTreeViewPlusNode in treeViewPlusNode.Nodes) { ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode childNode = FindNodeRecursive(childTreeViewPlusNode, nodeName); if (childNode != null) return childNode; } // If the code reaches this point, no match was found. return null; } // Retrieves the first control of the passed-in type from the passed-in control collection public static System.Web.UI.Control FindControlOfType(System.Type type, System.Web.UI.ControlCollection controlCollection) { // Iterate through all the controls in the passed-in control collection foreach (System.Web.UI.Control webControl in controlCollection) { // If the current control is of the passed-in type, return it. if (type.IsInstanceOfType(webControl)) return webControl; else if (webControl.HasControls()) { // The current control has child controls, so call this function on those child controls System.Web.UI.Control childWebControl = FindControlOfType(type, webControl.Controls); if (childWebControl != null) return childWebControl; } } // If the code reaches this point, no match was found. return null; } // Finds a control by checking whether the passed-in control or any child controls have an ID matching the // passed-in control ID public static System.Web.UI.Control FindControlRecursive(System.Web.UI.Control webControl, string controlID) { // If the passed-in control has an ID that matches the passed-in ID, return it if (webControl.ID == controlID) return webControl; // Iterate through the child control's of the current control, calling this function on each foreach (System.Web.UI.Control childWebControl in webControl.Controls) { System.Web.UI.Control matchingControl = FindControlRecursive(childWebControl, controlID); if (matchingControl != null) { return matchingControl; } } // If the code reaches this point, no match was found. return null; } } }