ArcGIS Add Dynamic Data
ArcGIS_AddDynamicData_VBNet\CustomMapHandler_ADF.aspx.vb
' 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.
' 

' 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.
Partial Public Class CustomMapHandler_ADF
    Inherits System.Web.UI.Page
#Region "Instance Variable Declarations"

    Private _serverObjectStateModifier As ServerObjectStateModifier = Nothing

    ' Specify the name of the resource to target when adding/removing the dynamic layer
    Private _targetResourceName As String = "MapResourceItem0"
    ' Specify the name of the layer to be added/removed
    Private _dynamicLayerName As String = "us_lakes"

#End Region

#Region "ASP.NET Page Life Cycle Event Handlers"

    Public Sub Page_PreInit(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
        ' Instantiate a ServerObjectStateModifier object to use for adding and removing the dynamic layer
        _serverObjectStateModifier = New ServerObjectStateModifier()
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal eventArgs As System.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") IsNot Nothing) AndAlso (CBool(Session("dynamicLayerAdded"))) Then
                ' Get the dynamic layer's target resource and call the method to add the dynamic layer to it
                Dim agsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality = CType(Map1.GetFunctionality(_targetResourceName), ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)
                Dim mapResourceLocal As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal = CType(agsMapFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)
                _serverObjectStateModifier.AddLayer(mapResourceLocal, _dynamicLayerName)
            End If

            AddHandler MapResourceManager1.ResourcesDispose, AddressOf MapResourceManager1_ResourcesDispose
        Catch exception As System.Exception
            ' Check whether the page is loading asynchronously.  
            If ScriptManager1.IsInAsyncPostBack Then
                ' Get a callback result that will show an alert with information pertaining to the exception
                Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.GetErrorCallback(exception)
                ' Get the control that initiated the postback
                Dim control As System.Web.UI.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 TypeOf control Is ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl Then
                    Dim adfWebControl As ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl = TryCast(control, ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl)
                    adfWebControl.CallbackResults.Add(errorCallbackResult)
                ElseIf TypeOf control Is ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl Then
                    Dim adfCompositeControl As ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl = TryCast(control, ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl)
                    adfCompositeControl.CallbackResults.Add(errorCallbackResult)
                Else
                    Dim callbackResults As New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection()
                    callbackResults.Add(errorCallbackResult)
                    ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), False)
                End If
            Else
                ' Since the page is in full postback, write the javascript alert code directly to the response
                Dim jsErrorAlert As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception))
                Response.Write(jsErrorAlert)
            End If
        End Try
    End Sub

#End Region

#Region "Web ADF Control Event Handlers"

    Private Sub MapResourceManager1_ResourcesDispose(ByVal sender As Object, ByVal e As System.EventArgs)
        ' 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") IsNot Nothing) AndAlso (CBool(Session("dynamicLayerAdded"))) Then
            ' Get the dynamic layer's target resource and call the method to remove the dynamic layer from it
            Dim agsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality = CType(Map1.GetFunctionality(_targetResourceName), ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)
            Dim mapResourceLocal As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal = CType(agsMapFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)
            _serverObjectStateModifier.RemoveLayer(mapResourceLocal, _dynamicLayerName)
        End If
    End Sub

    Protected Sub Toc1_NodeChecked(ByVal sender As Object, ByVal treeViewPlusNodeArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs)
        Try
            Dim treeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = treeViewPlusNodeArgs.Node
            Dim tocLayer As ESRI.ArcGIS.ADF.Web.TocLayer = TryCast(treeViewPlusNode.Data, ESRI.ArcGIS.ADF.Web.TocLayer)

            If tocLayer Is Nothing Then
                Return
            End If

            ' 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 Then
                tocLayer.Visible = Not tocLayer.Visible
                Session("dynamicLayerVisible") = tocLayer.Visible
            End If
        Catch exception As System.Exception
            ' Get a callback that will show an alert containing information about the error and add it to the Toc's
            ' callback results
            Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.GetErrorCallback(exception)
            Toc1.CallbackResults.Add(errorCallbackResult)
        End Try
    End Sub

#End Region

#Region "ASP.NET Web Control Event Handlers"

    Public Sub AddLayerButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            Dim agsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality = CType(Map1.GetFunctionality(_targetResourceName), ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)
            Dim mapResourceLocal As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal = CType(agsMapFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)

            ' 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 exception As System.Exception
            ProcessError(exception)
        End Try
    End Sub

    Public Sub RemoveLayerButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            Dim agsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality = CType(Map1.GetFunctionality(_targetResourceName), ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)
            Dim mapResourceLocal As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal = CType(agsMapFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)

            ' 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 exception As System.Exception
            ProcessError(exception)
        End Try
    End Sub

#End Region

#Region "Instance Methods"

    ' Refreshes the Map and Toc controls and populates the callback results member variable with the
    ' resulting callback results 
    Public Sub RefreshMapAndToc()
        Toc1.Refresh()
        Map1.CallbackResults.CopyFrom(Toc1.CallbackResults)

        Map1.RefreshResource(_targetResourceName)
        Dim callbackResults As New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection()
        callbackResults.CopyFrom(Map1.CallbackResults)
        ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), False)
    End Sub

    Private Sub ProcessError(ByVal exception As System.Exception)
        ' Get a callback result that will alert the user of the error and add it to the callback results collection
        Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.GetErrorCallback(exception)
        Dim callbackResults As New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection()
        callbackResults.Add(errorCallbackResult)
        ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), False)
    End Sub

#End Region

End Class