ArcGIS Checkout and check-in geodata
ArcGIS_Checkout_Checkin_Geodata_CSharp\Default.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.
// 

public partial class _Default : System.Web.UI.Page
{
    #region Instance Variable Declarations

    // Specify the host and name of the geodata service for checkout/checkin
    private string m_hostName = "localhost";
    private string m_serviceName = "MontgomerySimple";

    #endregion

    #region ASP.NET Page Life Cycle Event Handlers

    protected void Page_PreRender(object sender, System.EventArgs eventArgs)
    {
        // Get the script manager parameters that are included in the current page request
        string scriptManagerParameters = Page.Request.Params[ScriptManager1.ID];

        // Get the src attribute of the ifmDownload iframe element
        string downloadUrl = 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 ((downloadUrl != null) && ((scriptManagerParameters == null) ||
        !scriptManagerParameters.Contains(btnCheckOut.ID)))
            ifmDownload.Attributes["src"] = null;
    }

    #endregion

    #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 void btnCheckOut_Click(object sender, System.EventArgs eventArgs)
    {
        try
        {
            // Get a reference to a proxy for the geodata service
            string geoDataServiceUrl = string.Format("http://{0}/arcgis/services/{1}/GeoDataServer",
                m_hostName, m_serviceName);
            ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy 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.
            ESRI.ArcGIS.ADF.ArcGISServer.esriWorkspaceType agsSoapWorkspaceType =
                geoDataServerProxy.GetWrappedWorkspaceType();
            if (agsSoapWorkspaceType != ESRI.ArcGIS.ADF.ArcGISServer.esriWorkspaceType.esriRemoteDatabaseWorkspace)
                throw new System.Exception("Geodata service is not hosting an ArcSDE geodatabase - which is required for replication."); 

            // Initialize a GP Replica Descripton object.  This will describe the properties of the dataset
            // to be checked out
            ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDescription agsSoapGpReplicaDescription =
                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.

            ESRI.ArcGIS.ADF.ArcGISServer.DEBrowseOptions agsSoapDEBrowseOptions =
                new ESRI.ArcGIS.ADF.ArcGISServer.DEBrowseOptions();
            agsSoapDEBrowseOptions.ExpandType = ESRI.ArcGIS.ADF.ArcGISServer.esriDEExpandType.esriDEExpandDescendants;
            agsSoapDEBrowseOptions.RetrieveFullProperties = true;
            agsSoapDEBrowseOptions.RetrieveMetadata = true;
            

            ESRI.ArcGIS.ADF.ArcGISServer.DataElement[] agsSoapDataElements =
                geoDataServerProxy.GetDataElements(agsSoapDEBrowseOptions);

            System.Collections.ArrayList replicaDatasetsList = new System.Collections.ArrayList();
            foreach (ESRI.ArcGIS.ADF.ArcGISServer.DataElement agsSoapDataElement in agsSoapDataElements)
            {
                if (agsSoapDataElement is ESRI.ArcGIS.ADF.ArcGISServer.DEFeatureClass)
                {
                    ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset agsSoapGpReplicaDataset =
                        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);
                }
                else if(agsSoapDataElement is ESRI.ArcGIS.ADF.ArcGISServer.DEFeatureDataset)
                {
                    
                    ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset agsSoapGpReplicaDataset =
                        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);
                }
                else if (agsSoapDataElement is ESRI.ArcGIS.ADF.ArcGISServer.DETable)
                {
                    ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset agsSoapGpReplicaDataset =
                        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;                   

                    // Add the dataset to the list
                    replicaDatasetsList.Add(agsSoapGpReplicaDataset);
                }
            }           

            // Copy the list to an array
            ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset[] agsSoapGpReplicaDatasets =
                new ESRI.ArcGIS.ADF.ArcGISServer.GPReplicaDataset[replicaDatasetsList.Count];

            replicaDatasetsList.CopyTo(agsSoapGpReplicaDatasets);

            //It is important to expand the replica dataset in order to get the relationship classes.
            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
            ESRI.ArcGIS.ADF.ArcGISServer.GDSExportOptions agsSoapGdsExportOptions =
                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.
            System.Random randomizer = new System.Random();
            int randomNumber = randomizer.Next(0, int.MaxValue);
            string replicaName = string.Format("replica_{0}", randomNumber.ToString());

            string defaultVersion = geoDataServerProxy.GetDefaultWorkingVersion();
            if (string.IsNullOrEmpty(defaultVersion))
                throw new System.Exception("No versioned data found: replication requires versioned data."); 
            
            // 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
            ESRI.ArcGIS.ADF.ArcGISServer.GDSData agsSoapGdsData = geoDataServerProxy.CreateReplica(
                defaultVersion, replicaName, agsSoapGpReplicaDescription,
                null, 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 (System.Exception exception)
        {
            // Update the error label with the the exception message
            lblError.Text = exception.Message;
        }
    }

    // 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 void btnCheckIn_Click(object sender, System.EventArgs eventArgs)
    {
        try
        {
            // Get a reference to the file that was posted to the server via the FileUpload control
            System.Web.HttpPostedFile httpPostedFile = inFile.PostedFile;

            // Exit the function if no file was posted to the server
            if (httpPostedFile == null)
                return;

            // Notify the user and exit if the posted file is empty
            int fileSize = httpPostedFile.ContentLength;
            if (fileSize <= 0)
            {
                lblError.Text = "The specified file has no data.";
                return;
            }

            // Make sure that the posted file is a personal geodatabase
            if (System.IO.Path.GetExtension(httpPostedFile.FileName) != ".mdb")
            {
                lblError.Text = "The specified file is not a personal geodatabase.";
                return;
            }

            // Save the posted file to the temp directory 
            string tempPostedFileName = 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
            System.IO.FileStream postedFileStream = new System.IO.FileStream(tempPostedFileName,
                System.IO.FileMode.Open);
            byte[] postedFileByteArray = new byte[postedFileStream.Length];
            postedFileStream.Read(postedFileByteArray, 0, (int)postedFileStream.Length);

            // Instantiate an ArcGIS Server SOAP GDSData object with the posted file's contents
            ESRI.ArcGIS.ADF.ArcGISServer.GDSData agsSoapGdsData =
                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
            string geoDataServiceUrl = string.Format("http://{0}/arcgis/services/{1}/GeoDataServer",
                m_hostName, m_serviceName);
            ESRI.ArcGIS.ADF.ArcGISServer.GeoDataServerProxy 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 (System.Exception exception)
        {
            // Update the error label with the the exception message
            lblError.Text = exception.Message;
        }
    }

    #endregion
}