ArcGIS Checkout and check-in geodata
ArcGIS_Checkout_Checkin_Geodata_VBNet\Default.aspx.vb
' 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.
' 

Imports Microsoft.VisualBasic
Imports System
Public Partial Class _Default
  Inherits System.Web.UI.Page
  #Region "Instance Variable Declarations"

  ' Specify the host and name of the geodata service for checkout/checkin
  Private m_hostName As String = "localhost"
    Private m_serviceName As String = "MontgomerySimple"

  #End Region

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

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    ' Get the script manager parameters that are included in the current page request
    Dim scriptManagerParameters As String = Page.Request.Params(ScriptManager1.ID)

    ' Get the src attribute of the ifmDownload iframe element
    Dim downloadUrl As String = ifmDownload.Attributes("src")

    ' If the src attribute is non-null and the script manager parameters indicate
    ' that the current request was not generated by clicking the check out button,
    ' then the src attribute of the iframe needs to be reset to prevent downloading
    ' the last checkout database
    If (Not downloadUrl Is Nothing) AndAlso ((scriptManagerParameters Is Nothing) OrElse (Not scriptManagerParameters.Contains(btnCheckOut.ID))) Then
      ifmDownload.Attributes("src") = Nothing
    End If
  End Sub

  #End Region

  #Region "ASP.NET Web Control Event Handlers"

  ' Fires when the Check Out button is clicked.  Makes a database containing features 
  ' within the current extent available for download.
  Protected Sub btnCheckOut_Click(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    Try
      ' Get a reference to a proxy for the geodata service
      Dim geoDataServiceUrl As String = String.Format("http://{0}/arcgis/services/{1}/GeoDataServer", m_hostName, m_serviceName)
      Dim geoDataServerProxy As ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy = New ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy(geoDataServiceUrl)

      ' Check workspace type.  Only geodata services hosting ArcSDE geodatabases can create replicas.  
      ' If the following method returns esriRemoteDatabaseWorkspace, replication (if enabled) will work.
      Dim agsSoapWorkspaceType As ESRI.ArcGIS.ADF.ArcGISServer.esriWorkspaceType = geoDataServerProxy.GetWrappedWorkspaceType()
            If Not agsSoapWorkspaceType = ESRI.ArcGIS.ADF.ArcGISServer.esriWorkspaceType.esriRemoteDatabaseWorkspace Then
                Throw New System.Exception("Geodata service is not hosting an ArcSDE geodatabase - which is required for replication.")
            End If

      ' Initialize a GP Replica Descripton object.  This will describe the properties of the dataset
      ' to be checked out
      Dim agsSoapGpReplicaDescription As ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDescription = New ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDescription()
      agsSoapGpReplicaDescription.ModelType = ESRI.ArcGIS.ADF.ArcGISServer.esriReplicaModelType.esriModelTypeFullGeodatabase
      agsSoapGpReplicaDescription.SingleGeneration = True
      agsSoapGpReplicaDescription.TransferRelatedObjects = True

      ' Initialize the replica description with the current map extent and a spatial relationship of
      ' contains so that only features fully within the current map extent are checked out
      agsSoapGpReplicaDescription.QueryGeometry = ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.FromAdfGeometry(Map1.Extent)
      agsSoapGpReplicaDescription.SpatialRelation = ESRI.ArcGIS.ADF.ArcGISServer.esriSpatialRelEnum.esriSpatialRelIntersects

      ' Create the list of datasets to be checked out.  Note that the DatasetName for each 
      ' GPReplicaDataset must be the fully qualified database name.  These database names can only 
      ' be retrieved programmatically via ArcObjects, so an application that relies solely on the 
      ' Web ADF for geospatial functionality must hard code the dataset names, as shown here.

      Dim agsSoapDEBrowseOptions As ESRI.ArcGIS.ADF.ArcGISServer.DEBrowseOptions = New ESRI.ArcGIS.ADF.ArcGISServer.DEBrowseOptions()
      agsSoapDEBrowseOptions.ExpandType = ESRI.ArcGIS.ADF.ArcGISServer.esriDEExpandType.esriDEExpandDescendants
      agsSoapDEBrowseOptions.RetrieveFullProperties = True
      agsSoapDEBrowseOptions.RetrieveMetadata = True

      Dim agsSoapDataElements As ESRI.ArcGIS.ADF.ArcGISServer.DataElement() = geoDataServerProxy.GetDataElements(agsSoapDEBrowseOptions)

      Dim replicaDatasetsList As System.Collections.ArrayList = New System.Collections.ArrayList()
      For Each agsSoapDataElement As ESRI.ArcGIS.ADF.ArcGISServer.DataElement In agsSoapDataElements
        If TypeOf agsSoapDataElement Is ESRI.ArcGIS.ADF.ArcGISServer.DEFeatureClass Then
          Dim agsSoapGpReplicaDataset As ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset = New ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset()

          agsSoapGpReplicaDataset.DatasetName = agsSoapDataElement.Name

          ' Specify properties that will be the same for each dataset to be checked out
          agsSoapGpReplicaDataset.DatasetType = ESRI.ArcGIS.ADF.ArcGISServer.esriDatasetType.esriDTFeatureClass
          agsSoapGpReplicaDataset.RowsType = ESRI.ArcGIS.ADF.ArcGISServer.esriRowsType.esriRowsTypeFilter
          agsSoapGpReplicaDataset.UseGeometry = True

          ' Add the dataset to the list
          replicaDatasetsList.Add(agsSoapGpReplicaDataset)
                End If
                If TypeOf agsSoapDataElement Is ESRI.ArcGIS.ADF.ArcGISServer.DEFeatureDataset Then
                    Dim agsSoapGpReplicaDataset As ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset = New ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset()

                    agsSoapGpReplicaDataset.DatasetName = agsSoapDataElement.Name

                    ' Specify properties that will be the same for each dataset to be checked out
                    agsSoapGpReplicaDataset.DatasetType = ESRI.ArcGIS.ADF.ArcGISServer.esriDatasetType.esriDTFeatureDataset
                    agsSoapGpReplicaDataset.RowsType = ESRI.ArcGIS.ADF.ArcGISServer.esriRowsType.esriRowsTypeFilter
                    agsSoapGpReplicaDataset.UseGeometry = True

                    ' Add the dataset to the list
                    replicaDatasetsList.Add(agsSoapGpReplicaDataset)
                End If
                If TypeOf agsSoapDataElement Is ESRI.ArcGIS.ADF.ArcGISServer.DETable Then
                    Dim agsSoapGpReplicaDataset As ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset = New ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset()

                    agsSoapGpReplicaDataset.DatasetName = agsSoapDataElement.Name

                    ' Specify properties that will be the same for each dataset to be checked out
                    agsSoapGpReplicaDataset.DatasetType = ESRI.ArcGIS.ADF.ArcGISServer.esriDatasetType.esriDTTable
                    agsSoapGpReplicaDataset.RowsType = ESRI.ArcGIS.ADF.ArcGISServer.esriRowsType.esriRowsTypeFilter

                    ' Add the dataset to the list
                    replicaDatasetsList.Add(agsSoapGpReplicaDataset)
                End If
      Next agsSoapDataElement

      ' Copy the list to an array
      Dim agsSoapGpReplicaDatasets As ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset() = New ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset(replicaDatasetsList.Count - 1){}
            replicaDatasetsList.CopyTo(agsSoapGpReplicaDatasets)

            'It is important to expand the GpReplicaDataset in order to retrieve Relationshipclasses in schema.
            agsSoapGpReplicaDatasets = geoDataServerProxy.ExpandReplicaDatasets(agsSoapGpReplicaDatasets)

      ' Associate the dataset list with the replica description object
      agsSoapGpReplicaDescription.GPReplicaDatasets = agsSoapGpReplicaDatasets

      ' Instantiate an export options object to specify the export format as personal 
      ' geodatabase
      Dim agsSoapGdsExportOptions As ESRI.ArcGIS.ADF.ArcGISServer.GDSExportOptions = New ESRI.ArcGIS.ADF.ArcGISServer.GDSExportOptions()
      agsSoapGdsExportOptions.ExportFormat = ESRI.ArcGIS.ADF.ArcGISServer.esriGDSExportFormat.esriGDSExportFormatPersonalGdb

      ' Create a random replica name.  If a replica with the same name has been created previously,
      ' replica creation will fail.
      Dim randomizer As System.Random = New System.Random()
      Dim randomNumber As Integer = randomizer.Next(0, Integer.MaxValue)
      Dim replicaName As String = String.Format("replica_{0}", randomNumber.ToString())

      Dim defaultVersion As String = geoDataServerProxy.GetDefaultWorkingVersion()
      If String.IsNullOrEmpty(defaultVersion) Then
        Throw New System.Exception("No versioned data found: replication requires versioned data.")
      End If

      ' Create the replica (checkout) database, layers must be versioned in host geodatabase
      ' See help for more info: http://webhelp.esri.com/arcgisserver/9.3/dotNet/index.htm#geodatabases/creating_replicas.htm
      Dim agsSoapGdsData As ESRI.ArcGIS.ADF.ArcGISServer.GDSData = geoDataServerProxy.CreateReplica(defaultVersion, replicaName, agsSoapGpReplicaDescription, Nothing, agsSoapGdsExportOptions, ESRI.ArcGIS.ADF.ArcGISServer.esriGDSTransportType.esriGDSTransportTypeUrl)

      ' Assign the url of the replica to the hidden iframe element's src property.  The partial postback
      ' response will include this frame, along with the updated src property, since the frame is in an 
      ' UpdatePanel.  When the updated frame is rendered, it will attempt to render the content referred 
      ' to by the src attribute, which, in this case, will trigger a download of the replica database.
      ' In order for the IFRAME solution to work, clients will either need to be on the local network (intranet) 
      ' or they will need to add the site on which this page is hosted to their trusted site list. 
      ifmDownload.Attributes.Add("src", agsSoapGdsData.URL)
    Catch exception As System.Exception
      ' Update the error label with the the exception message
      lblError.Text = exception.Message
    End Try
  End Sub

  ' Fires when the Check In button is clicked.  Attempts to update the database specified
  ' by the instance variables with that contained in the user-specified database 
  Protected Sub btnCheckIn_Click(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    Try
      ' Get a reference to the file that was posted to the server via the FileUpload control
      Dim httpPostedFile As System.Web.HttpPostedFile = inFile.PostedFile

      ' Exit the function if no file was posted to the server
      If httpPostedFile Is Nothing Then
        Return
      End If

      ' Notify the user and exit if the posted file is empty
      Dim fileSize As Integer = httpPostedFile.ContentLength
      If fileSize <= 0 Then
        lblError.Text = "The specified file has no data."
        Return
      End If

      ' Make sure that the posted file is a personal geodatabase
      If System.IO.Path.GetExtension(httpPostedFile.FileName) <> ".mdb" Then
        lblError.Text = "The specified file is not a personal geodatabase."
        Return
      End If

      ' Save the posted file to the temp directory 
      Dim tempPostedFileName As String = System.IO.Path.GetTempFileName()
      tempPostedFileName = System.IO.Path.ChangeExtension(tempPostedFileName, ".mdb")
      httpPostedFile.SaveAs(tempPostedFileName)

      ' Copy the contents of the posted file to a byte array
      Dim postedFileStream As System.IO.FileStream = New System.IO.FileStream(tempPostedFileName, System.IO.FileMode.Open)
      Dim postedFileByteArray As Byte() = New Byte(postedFileStream.Length - 1){}
      postedFileStream.Read(postedFileByteArray, 0, CInt(Fix(postedFileStream.Length)))

      ' Instantiate an ArcGIS Server SOAP GDSData object with the posted file's contents
      Dim agsSoapGdsData As ESRI.ArcGIS.ADF.ArcGISServer.GDSData = New ESRI.ArcGIS.ADF.ArcGISServer.GDSData()
      agsSoapGdsData.TransportType = ESRI.ArcGIS.ADF.ArcGISServer.esriGDSTransportType.esriGDSTransportTypeEmbedded
      agsSoapGdsData.EmbeddedData = postedFileByteArray

      ' Get a reference to a proxy for the geodata service
      Dim geoDataServiceUrl As String = String.Format("http://{0}/arcgis/services/{1}/GeoDataServer", m_hostName, m_serviceName)
      Dim geoDataServerProxy As ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy = New ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy(geoDataServiceUrl)

      ' Attempt to import the posted file into the database referenced by the geodata service
      geoDataServerProxy.ImportReplicaDataChanges(ESRI.ArcGIS.ADF.ArcGISServer.esriGDSReplicaImportSource.esriGDSReplicaImportSourceDeltaPersonalGDB, ESRI.ArcGIS.ADF.ArcGISServer.esriReplicaReconcilePolicyType.esriReplicaResolveConflictsInFavorOfImportedChanges, False, agsSoapGdsData)
    Catch exception As System.Exception
      ' Update the error label with the the exception message
      lblError.Text = exception.Message
    End Try
  End Sub

  #End Region
End Class