ArcGIS_AddDynamicData_CSharp\CustomMapHandler_ADF.aspx.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. // // Illustrates how to add a new layer dynamically to a pooled ArcGIS Server map service using Web ADF // controls and ArcObjects. The layer is added in a shallowly stateful way, meaning that it persists // in the users browser, but does not affect the map service when used by other clients. public partial class CustomMapHandler_ADF : System.Web.UI.Page { #region Instance Variable Declarations ServerObjectStateModifier _serverObjectStateModifier = null; // Specify the name of the resource to target when adding/removing the dynamic layer private string _targetResourceName = "MapResourceItem0"; // Specify the name of the layer to be added/removed private string _dynamicLayerName = "us_lakes"; #endregion #region ASP.NET Page Life Cycle Event Handlers public void Page_PreInit(object sender, System.EventArgs eventArgs) { // Instantiate a ServerObjectStateModifier object to use for adding and removing the dynamic layer _serverObjectStateModifier = new ServerObjectStateModifier(); } protected void Page_Load(object sender, System.EventArgs eventArgs) { try { // Register the add and remove layer buttons so they initiate asynchronous // postbacks when clicked ScriptManager1.RegisterAsyncPostBackControl(AddLayerButton); ScriptManager1.RegisterAsyncPostBackControl(RemoveLayerButton); // Store the name of the resource to target for dynamic layer addition/removal in session. We do this to share // this information with the custom map handler Session["targetResourceName"] = _targetResourceName; // If the dynamic layer is currently present (indicated by the session variable), then we need to re-add it so that // the Web ADF components accessing the map resource containing that layer are aware of its presence. if ((Session["dynamicLayerAdded"] != null) && ((bool)Session["dynamicLayerAdded"])) { // Get the dynamic layer's target resource and call the method to add the dynamic layer to it ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName); ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource; _serverObjectStateModifier.AddLayer(mapResourceLocal, _dynamicLayerName); } MapResourceManager1.ResourcesDispose += new System.EventHandler(MapResourceManager1_ResourcesDispose); } catch (System.Exception exception) { // Check whether the page is loading asynchronously. if (ScriptManager1.IsInAsyncPostBack) { // Get a callback result that will show an alert with information pertaining to the exception ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = Utility.GetErrorCallback(exception); // Get the control that initiated the postback System.Web.UI.Control control = Utility.GetPostBackControl(Page); // If the control is a Web ADF Control (i.e. WebCotnrol or CompositeControl), add the error // callback to that control's callback results. Otherwise, add the error callback to the // callback results collection member variable, which will be passed to the client in // GetCallbackResult. if (control is ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl) { ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl adfWebControl = control as ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl; adfWebControl.CallbackResults.Add(errorCallbackResult); } else if (control is ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl adfCompositeControl = control as ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl; adfCompositeControl.CallbackResults.Add(errorCallbackResult); } else { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection(); callbackResults.Add(errorCallbackResult); ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false); } } else { // Since the page is in full postback, write the javascript alert code directly to the response string jsErrorAlert = string.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } } #endregion #region Web ADF Control Event Handlers void MapResourceManager1_ResourcesDispose(object sender, System.EventArgs e) { // If the dynamic layer is currently present (indicated by the session variable), then we need to remove it from the // map service before the server context created as a result of the current page request is released. Otherwise, // the layer will remain in the map service outside the scope of this request, making it possible for this layer to // be seen by other clients. if ((Session["dynamicLayerAdded"] != null) && ((bool)Session["dynamicLayerAdded"])) { // Get the dynamic layer's target resource and call the method to remove the dynamic layer from it ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName); ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource; _serverObjectStateModifier.RemoveLayer(mapResourceLocal, _dynamicLayerName); } } protected void Toc1_NodeChecked(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs treeViewPlusNodeArgs) { try { ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode treeViewPlusNode = treeViewPlusNodeArgs.Node; ESRI.ArcGIS.ADF.Web.TocLayer tocLayer = treeViewPlusNode.Data as ESRI.ArcGIS.ADF.Web.TocLayer; if (tocLayer == null) return; // If the dynamic layer was clicked, change it's visibility in the Toc and store its new visibility in session. // We do this so that the proper visibility can be applied if the layer is removed and re-added. if (tocLayer.Name == _dynamicLayerName) { tocLayer.Visible = !tocLayer.Visible; Session["dynamicLayerVisible"] = tocLayer.Visible; } } catch (System.Exception exception) { // Get a callback that will show an alert containing information about the error and add it to the Toc's // callback results ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = Utility.GetErrorCallback(exception); Toc1.CallbackResults.Add(errorCallbackResult); } } #endregion #region ASP.NET Web Control Event Handlers public void AddLayerButton_Click(object sender, System.EventArgs e) { try { ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName); ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource; // Call the method to add the dynamic layer, which will add the layer to the map service. _serverObjectStateModifier.AddLayer(mapResourceLocal, _dynamicLayerName); // Refresh the Map and Toc controls so they show the layer. RefreshMapAndToc(); // Set session variables indicating the presence and name of the dynamic layer. We do this to share // this information with the custom map handler. Session["dynamicLayerAdded"] = true; Session["dynamicLayerName"] = _dynamicLayerName; } catch (System.Exception exception) { ProcessError(exception); } } public void RemoveLayerButton_Click(object sender, System.EventArgs e) { try { ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName); ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource; // Call the method to remove the dynamic layer, which will remove the layer from the map service. _serverObjectStateModifier.RemoveLayer(mapResourceLocal, _dynamicLayerName); // Refresh the Map and Toc controls so they do not show the layer. RefreshMapAndToc(); // Set the session variable indicating the absence of the dynamic layer Session["dynamicLayerAdded"] = false; } catch (System.Exception exception) { ProcessError(exception); } } #endregion #region Instance Methods // Refreshes the Map and Toc controls and populates the callback results member variable with the // resulting callback results public void RefreshMapAndToc() { Toc1.Refresh(); Map1.CallbackResults.CopyFrom(Toc1.CallbackResults); Map1.RefreshResource(_targetResourceName); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection(); callbackResults.CopyFrom(Map1.CallbackResults); ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false); } private void ProcessError(System.Exception exception) { // Get a callback result that will alert the user of the error and add it to the callback results collection ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = Utility.GetErrorCallback(exception); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection(); callbackResults.Add(errorCallbackResult); ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false); } #endregion }