Getting "Invalid file or corrupted file" Exception when Opening Map Cache after Sync

3028
1
04-05-2012 06:27 AM
KevinBupp
New Contributor III
Ok, So I have this Windows Mobile 6 ArcGIS Mobile 10 SDK application that I can get to run wonderfully as long as I have created a mobile cache and physically placed it onto the device.

But whenever I try to use a MobileServiceConnection, MobileCache, and MobileCacheSyncAgent to Synchronize my map with the MapServer on my ArcGIS Server I get a "Invalid file or corrupted file" exception as soon as I try to open the MobileCache.

I checked the ArcGIS Server logs and it appears to be receiving the request, and processing it correctly:
Level Message         Time   Configuration
INFO3 Server Context released.      2012-03-23 17:40:37 Facilities.MapServer 
INFO2 Binary request successfully processed. Response size is 2136 bytes. 2012-03-23 17:40:37 Facilities.MapServer 
DEBUG MobileSync: Get Schema [elapsed time = 0.001189 seconds].  2012-03-23 17:40:37 Facilities.MapServer 
DEBUG Schema Checksum 2197403820.      2012-03-23 17:40:37 Facilities.MapServer 
INFO2 Binary request received. Request size is 5 bytes.   2012-03-23 17:40:37 Facilities.MapServer 
INFO3 Server Context created.       2012-03-23 17:40:37 Facilities.MapServer

Here is my code:
            try
            {
                if (!Utility.CheckURLConnection(AppProps.MobileMapServiceURL + "?wsdl"))
                {
                    MessageBox.Show("Not able to connect to map server.");
                }
                mobileMapServiceCache.StoragePath = mobileMapServiceCachePath;
                mobileMapServiceCache.DeleteCache();
                mobileMapServiceConn.Url = AppProps.MobileMapServiceURL;
                MobileCacheSyncAgent mobileSync = new MobileCacheSyncAgent(mobileMapServiceCache, mobileMapServiceConn);
                if (mobileSync.IsValid)
                {
                    mobileMapServiceConn.CreateCache(mobileMapServiceCache);
                    //mobileSync.StateChanged += new EventHandler(mobileSync_StateChanged);
                    //mobileSync.ProgressChanged += new EventHandler<MobileCacheSyncAgentProgressEventArgs>(mobileSync_ProgressChanged);
                    SyncResults mobileResults = mobileSync.Synchronize();
                    MessageBox.Show(mobileResults.DataSizeReceived.ToString());
                    mobileMapServiceCache.Open();
                    map1.DataSources.Add(mobileMapServiceCache);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Cannot synchronize with the mobile map service: " + ex.Message);
            }


I even tried adding event handlers to the MobileCacheSyncAgent ... but they were never called ...

The MessageBox right before the mobileMapServiceCache.Open(); call always return 0 ...

back in 9.3.1 all we had to do was use a MobileService ... am I doing something wrong? Please help!

Furthermore, I have tried the following with no success

  •     downloading and installing the latest build of ArcGIS Mobile (build 2550)

  •     Enabling Feature Access on the MapService

  •     changing the map service from pooled to non-pooled

  •     using a different/simple Map Service with only 1 featurelayer

  •     breaking the synchronize process down to synchronizing each FeatureLayer individually with the FeatureLayerSyncAgent

  •     Setting the SynchronizationDirection to SyncDirection.DownloadOnly

  •     changing the WebClientProtocolType to WebClientProtocolType.SoapWebService

  •     using DownloadExtent instead of Synchronize

  •     compiled the application in Release (instead of debug)

  •     tried it on a different Emulator

  •     tried it on an actual device


I have also discovered that in the MobileCache directory, the only file that is getting updated is the MobileCache.db-journal.

Deleting the contents of the db-journal file (or simply deleting the file) allows the application to open the MapCache correctly. However, it does not have any of the new data from the map service.

Somehow, the DownloadExtent/Synchronize process correctly makes a request to ArcGIS Server, gets a response back and then writes some junk in the .db-journal file, thus corrupting my local map cache and not actually getting any of the new data.

maybe someone can explain how the process is supposed to work and how the files in the MobileCache directory are supposed to be updated to help me narrow down the problem.

In case you are curious ... here is one example of what the db-journal is populating with:
�?�?ù ¡c�?   ï�?e�?�                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               /
   �? �?                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ' #2sde.DEFAULT"  �?  �?þÿÿÿ�?ê�?ÿï�?e�?�   SQLite format 3   @     3            �?                                                         <Á    ãûöñìçâÝ�?�?�?�?�?¿ºµ°«¦¡�?�??�??�?�?~ytoje`[VQLGB=83-'! ý÷ñëå�?�?�?Í�?Á                                                                                                                                          #GGEtablelayer0_current_spatial_parentlayer0_current_spatial_parentCREATE TABLE "layer0_current_spatial_parent"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)EE9tablelayer0_current_spatial_rowidlayer0_current_spatial_rowidCREATE TABLE "layer0_current_spatial_rowid"(rowid INTEGER PRIMARY KEY, nodeno INTEGER)CC/   �?A   �?>   �?:   Ё5   �?1   �?-   �?(   ¿&   ½"   ¸    µ   °   ®   ©   ¦   ¡   Ÿ   š   �??   �??   {   �?�y   �?t   �?r   �?�m   {k   yf   te   r`   p_   k\   iY   dX   bS   ]R   ZM   UK   SG   NE   K@   F>   C9   >7   <2   71   5,   3+   .(   ,%   '$   %                       
      ï�?f`



I originally posted this over in the ArcGIS Mobile Forum, but was unable to get any help 😞 ... not sure if this forum will get any more attention or not but I figured it was worth a shot 🙂

Thanks in advance!
-Kevin
0 Kudos
1 Reply
StevenSchuldt
New Contributor
I realize it was a while ago that you posted your question,  but since I recently had a cache problem of my own (and wish these boards were more active!), I figured I'd see if I could help at all.

It appears you're doing or have done most of the same things my program does - the main difference I see in the code you use and what I do (I'm on the Win32 version) is that I create and open the cache before synchronizing with FeatureLayerSyncAgents.

I remember I was getting the same error as you a while ago when I started developing with the 10 SDK - I fixed it but don't recall the details.

Anyway, here's what my code does - I've omitted parts and clipped out some stuff, but you should be able to see the main procedures (sorry it's messy, don't have time to streamline it to make it clear.)

Good luck

  


  private void frmMain_Load(object sender, EventArgs e) {

   // Specify the mobileservice URL
   CacheStoragePath = String.Format(@"{0}\GPS_Cache", Common.GetDataRootPath());

   //Setup the layer sync object
   InitializeSyncMaster();

   //If we're going to create a new map cache, archive the previous one so we don't ever delete data on accident
   CacheOpenMode mode = MapHelpers.GetCacheOpenMode();

   //set security credentials to connect to the mobile service
   ConfigureServiceConnectionSecurity(this.mobileServiceConnection1);

   //download or initialize / open the map cache
   InitializeCache(this.mobileServiceConnection1, this.mobileCache1, CacheStoragePath, mode);
   mobileCache1.Open();

   //if we don't have any data in the cache start downloading
   if (mobileCache.IsEmpty) {
    IsInitializingData = true;
    BeginDownloadData(true);
   } 

  }

  private CredentialCache ConfigureServiceConnectionSecurity(MobileServiceConnection serviceConnection) {

   mobileServiceConnection1.WebClientProtocolType = WebClientProtocolType.BinaryWebService;

//OMITTED CODE WHERE I SET UP MY USER CREDENTIALS 

   NetworkCredential credentials = new NetworkCredential(String.Format(@"{0}\{1}", serverID, serverLoginUser), serverLoginPassword);
   CredentialCache credentialscache = new CredentialCache();

   serviceConnection.Url = Common.GetConfigValue("MobileServiceURL");
   credentialscache.Add(new Uri(Common.GetConfigValue("MobileServiceURL")), "Basic", credentials);
   serviceConnection.WebClientProtocol.Credentials = credentialscache;
   return credentialscache;
  }

  private void InitializeSyncMaster() {
   SyncMaster = new MobileCacheSyncAgent(mobileCache1);
   SyncMaster.MapDocumentConnection = mobileServiceConnection1;
   SyncMaster.ProgressChanged += SyncMaster_ProgressChanged;
   SyncMaster.StateChanged += SyncMaster_StateChanged;
   this.SyncResults = new SyncResults(this.SyncMaster);
  }

  public void BeginDownloadData(bool initializeSyncAgents) {

   if (initializeSyncAgents) {
    SetupSyncAgents();
   }

   if (this.mobileServiceConnection1.IsValid) {
    SyncMaster.BeginDownloadExtent(map1.GetFullExtent(), 0, 0, DownloadExtent, Guid.NewGuid());
   }

  }

  public void SetupSyncAgents(List<string> LayersToSync) {

   this.DisplayedNotConnectedErrorMessage = false;

   if (SyncMaster.SyncAgents != null && SyncMaster.SyncAgents.Count() > 0) {
    this.SyncResults.SyncResultsDataTable.Rows.Clear();
    SyncMaster.SyncAgents.Clear();
   }

   foreach (string layerName in LayersToSync) {

    Layer l = this.mobileCache.Layers[layerName];

    if (l is FeatureLayer) {
     var fl = (FeatureLayer)l;
     FeatureLayerSyncAgent agent = new FeatureLayerSyncAgent(fl);
     agent.ProgressChanged += FeatureLayerAgent_ProgressChanged;
     if (Common.IsLayerValidForProjectFilter(agent)) {
      agent.DownloadFilter = new QueryFilter(String.Format("ProjectID = {0}", Common.ProjectID));
     }
     agent.MapDocumentConnection = this.mobileServiceConnection1;
     agent.SynchronizationDirection = SyncDirection.DownloadOnly;
     SyncMaster.SyncAgents.Add(agent);
    }

    if (l is RasterLayer) {
     var rl = (RasterLayer)l;
     RasterLayerSyncAgent agent = new RasterLayerSyncAgent(rl);
     agent.Extent = this.map1.GetExtent();
     agent.MapDocumentConnection = this.mobileServiceConnection1;
     SyncMaster.SyncAgents.Add(agent);
    }
   }

   if (LayersToSync.Count() > 0) {
    this.SyncResults.InitializeList();
   }
  }

  public void SetupSyncAgents() {

   var layers = new List<string>();

   foreach (Layer l in this.mobileCache1.Layers) {
    if (!Common.IsSurveyCoverageMode || (Common.IsSurveyCoverageMode && l.Name != Layers.ARCH_SurveyCoverage )) {
     layers.Add(l.Name);
    }
   }

   SetupSyncAgents(layers);
  }

  private void InitializeCache(MobileServiceConnection serviceConnection, MobileCache cache, string cacheStoragePath, CacheOpenMode mode) {

   if (cache != null && cache.IsOpen) {
    cache.Close();
   }

   //location of cache files
   cache.StoragePath = cacheStoragePath;
   try {

    this.ConfigureServiceConnectionSecurity(serviceConnection);

    switch (mode) {
     case CacheOpenMode.Create:
      ArchiveMapCache();
      cache.DeleteCache();
      serviceConnection.CreateCache(cache);
      break;
     case CacheOpenMode.CreateNew:
      if (cache.CacheExists) {
       throw new NotSupportedException("Values for CacheOpenMode must be Create, Open, or CreateOrOpen");
      }
      break;
     case CacheOpenMode.OpenOrCreate:
      if (!cache.CacheExists) {
       serviceConnection.CreateCache(cache);
       Log.Write(String.Format("Program was set to CacheOpenMode.OpenOrCreate but not cache file was found at {0}.  Downloading a new cache.", this.CacheStoragePath));
      }
      break;
     case CacheOpenMode.Open:
      if (!cache.CacheExists) {
       serviceConnection.CreateCache(cache);
       Log.Write(String.Format("Program was set to CacheOpenMode.Open but no map cache was found at {0}.  Downloading a new cache.", this.CacheStoragePath));
      }
      break;
    }
   } catch (WebException ex) {
   }
  }
0 Kudos