Can not delete feature from Local Server under ArcGIS Runtime 100.12 (feature gets deleted successfully then reappears)

10-27-2021 01:58 AM
New Contributor


After upgrading from ArcGIS Runtime 100.9 to 100.12, I can no longer delete features from a ServiceFeatureTable provided using a LocalServer.

More exactly, the code for deleting the feature executes just fine, the number of features in the feature table decreases, but if I zoom in/out, the deleted feature reappears.

I have stitched together a simple test app from the following ArcGIS Runtime Samples: Local Server Services, Feature Layer Selection, Delete Features (feature service)

The result is the same. When I tap a feature it gets deleted and the count decreases from 17 to 16. It stays at 16 while I move the map around, but once I zoom the feature pops back into existence and the feature count is 17.

Note: I have also tried using Esri.ArcGISRuntime.LocalServices version 100.9 in combination with Esri.ArcGISRuntime 100.12 or 100.11, but had the same results.

using Esri.ArcGISRuntime;
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.LocalServices;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.UI.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1 {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {

        LocalFeatureService _localFeatureService;
        FeatureLayer _featureLayer;

        public MainWindow() {


        private async void Initialize() {
            // Create a map and add it to the view
            MyMapView.Map = new Map(Basemap.CreateImagery());

            try {
                // LocalServer must not be running when setting the data path.
                if (LocalServer.Instance.Status == LocalServerStatus.Started) {
                    await LocalServer.Instance.StopAsync();

                // Set the local data path - must be done before starting. On most systems, this will be C:\EsriSamples\AppData.
                // This path should be kept short to avoid Windows path length limitations.
                string tempDataPathRoot = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.Windows)).FullName;
                string tempDataPath = System.IO.Path.Combine(tempDataPathRoot, "EsriSamples", "AppData");
                Directory.CreateDirectory(tempDataPath); // CreateDirectory won't overwrite if it already exists.
                LocalServer.Instance.AppDataPath = tempDataPath;

                // Start the local server instance
                await LocalServer.Instance.StartAsync();
            } catch (Exception ex) {
                var localServerTypeInfo = typeof(LocalMapService).GetTypeInfo();
                var localServerVersion = FileVersionInfo.GetVersionInfo(localServerTypeInfo.Assembly.Location);

                MessageBox.Show($"Please ensure that local server {localServerVersion.FileVersion} is installed prior to using the sample. The download link is in the description. Message: {ex.Message}", "Local Server failed to start");

            // Load the sample data and get the path
            string myfeatureServicePath = GetFeatureLayerPath();

            // Create the feature service to serve the local data
            _localFeatureService = new LocalFeatureService(myfeatureServicePath);

            // Listen to feature service status changes
            _localFeatureService.StatusChanged += _localFeatureService_StatusChanged;

            // Start the feature service
            try {
                await _localFeatureService.StartAsync();
            } catch (Exception ex) {
                MessageBox.Show(ex.Message, "The feature service failed to load");

        private async void _localFeatureService_StatusChanged(object sender, StatusChangedEventArgs e) {
            // Load the map from the service once ready
            if (e.Status == LocalServerStatus.Started) {
                // Get the path to the first layer - the local feature service url + layer ID
                string layerUrl = _localFeatureService.Url + "/0";

                // Create the ServiceFeatureTable
                ServiceFeatureTable myFeatureTable = new ServiceFeatureTable(new Uri(layerUrl));

                // Create the Feature Layer from the table
                _featureLayer = new FeatureLayer(myFeatureTable);

                // Add the layer to the map

                try {
                    // Wait for the layer to load
                    await _featureLayer.LoadAsync();

                    // Set the viewpoint on the MapView to show the layer data
                    await MyMapView.SetViewpointGeometryAsync(_featureLayer.FullExtent, 50);

                    MyMapView.GeoViewTapped += OnMapViewTapped;
                } catch (Exception ex) {
                    MessageBox.Show(ex.ToString(), "Error");

        private async void OnMapViewTapped(object sender, GeoViewInputEventArgs e) {
            try {
                // Define the selection tolerance.
                double tolerance = 15;

                // Convert the tolerance to map units.
                double mapTolerance = tolerance * MyMapView.UnitsPerPixel;

                // Get the tapped point.
                MapPoint geometry = e.Location;

                // Normalize the geometry if wrap-around is enabled.
                //    This is necessary because of how wrapped-around map coordinates are handled by Runtime.
                //    Without this step, querying may fail because wrapped-around coordinates are out of bounds.
                if (MyMapView.IsWrapAroundEnabled) {
                    geometry = (MapPoint)GeometryEngine.NormalizeCentralMeridian(geometry);

                // Define the envelope around the tap location for selecting features.
                Envelope selectionEnvelope = new Envelope(geometry.X - mapTolerance, geometry.Y - mapTolerance, geometry.X + mapTolerance,
                    geometry.Y + mapTolerance, MyMapView.Map.SpatialReference);

                // Define the query parameters for selecting features.
                QueryParameters queryParams = new QueryParameters
                    // Set the geometry to selection envelope for selection by geometry.
                    Geometry = selectionEnvelope

                // Select the features based on query parameters defined above.
                ServiceFeatureTable table = (ServiceFeatureTable)_featureLayer.FeatureTable;
                long featureCountOld = table.NumberOfFeatures;
                bool deletedStuff = false;
                var results = await _featureLayer.SelectFeaturesAsync(queryParams, Esri.ArcGISRuntime.Mapping.SelectionMode.New);
                foreach (var feature in results) {
                    // delete feature from feature table
                    await table.DeleteFeatureAsync(feature);
                    // Sync the change with the service.
                    await table.ApplyEditsAsync();

                    deletedStuff = true;
                long featureCountNew = table.NumberOfFeatures;

                if (deletedStuff) {
                    MessageBox.Show($"Deleted features, feature count changed from {featureCountOld} to {featureCountNew}");
                } else {
                    MessageBox.Show($"Nothing deleted, feature count is {featureCountOld}");
            } catch (Exception ex) {
                MessageBox.Show(ex.ToString(), "Error");

        private static string GetFeatureLayerPath() {
            return @"D:\PointsofInterest.mpkx";


0 Kudos
0 Replies