I'm trying to update the attributes of a feature layer through .Net. But I keep getting this error message: "Cannot call this method in this context: You must load the feature before editing."
Here is my code:
static void Main(string[] args) {
var featureTable = new ServiceFeatureTable(new Uri("https://services7.arcgis.com/yixziXsHssbXEWl5/ArcGIS/rest/services/grex/FeatureServer/0")) {Credential = new ArcGISTokenCredential()};
((TokenCredential) featureTable.Credential).Token = GetToken().access_token;
var queryParams = new QueryParameters {WhereClause = "DeelplanId = 666"};
// Query the feature table
var queryResult = featureTable.QueryFeaturesAsync(queryParams);
// Cast the QueryResult to a List so the results can be interrogated
queryResult.Wait();
var features = queryResult.Result.ToList();
features[0].SetAttributeValue("Kosten", 3562);
Console.ReadKey();
}
It fails on the SetAttributeValue, although I see the attributes are loaded from the server.
Any idea?, thx!
Solved! Go to Solution.
Hi, you have to call ArcGISFeature.LoadAsync Method for the feature before you can edit it.
var editFeature = features.First();
await (editFeature as ArcGISFeature).LoadAsync();
editFeature.SetAttributeValue("description", $"Updated from runtime at {DateTime.Now.ToShortTimeString()}");
Hi, you have to call ArcGISFeature.LoadAsync Method for the feature before you can edit it.
var editFeature = features.First();
await (editFeature as ArcGISFeature).LoadAsync();
editFeature.SetAttributeValue("description", $"Updated from runtime at {DateTime.Now.ToShortTimeString()}");
Hi Antti,
Yes that helped
But now the next problem:
I call
featureTable.UpdateFeatureAsync(features[0]).Wait();
after I set the new value but nothing happens: I don't see any request being made to the arcgis server and it doesn't raise an error as well. So how do I update the server with the new values?
thx again!
Hi Antii,
Never mind the last question I figured it out, u need to call ApplyEditsAsync to update the service. This is what I have so far:
static void Main(string[] args) {
var featureTable = new ServiceFeatureTable(new Uri("https://services7.arcgis.com/yixziXsHssbXEWl5/ArcGIS/rest/services/grex/FeatureServer/0")) {Credential = new ArcGISTokenCredential()}; ((TokenCredential) featureTable.Credential).Token = GetToken().access_token;
var queryParams = new QueryParameters {WhereClause = "DeelplanId = 666"}; //this will return max 2000 features
var queryResult = featureTable.QueryFeaturesAsync(queryParams);
queryResult.Wait();
var features = queryResult.Result.ToList();
foreach (var feature in features) {
if (CheckIfFeatureNeedsUpdate(feature)) {
((ArcGISFeature)feature).LoadAsync().Wait();
feature.Attributes["Kosten"] = 663584d;
//...update all other attributes
featureTable.UpdateFeatureAsync(feature).Wait();
}
}
featureTable.ApplyEditsAsync().Wait();
Console.ReadKey();
}
Is this the right way (from a design point of view ) to sync approximately 2000 records each day? Or is there a better more efficient way?
grt and thx again!
That's about right. You could easily get some performance improvements by parallelism and patch updates if you are doing a lot of work in a patches. Getting correct patch size figured out might need some performance diagnostics from your side based on the concrete requirements. In some cases you might want to do everything in one go though. If you are doing only attribute edits, then this isn't as important but if you are doing something with the geometry such as using GeometryEngine to validate / compare / manage the geometry, then there will be clear benefits to write a bit more code to get more speed out from it.
Anyway, you have the general usage working so rest is basically up on the real use case and decision how much time is worth to spend to optimize the behavior.
If you are planning to run this patch tool as a console app, i would recommend using something like this to enable proper use of async-await pattern http://blog.stephencleary.com/2012/02/async-console-programs.html
Edit: There might be also benefit to define which attributes / geometry is requested when the features are queried. See ServiceFeatureTable.QueryFeaturesAsync Method (QueryParameters, QueryFeatureFields), QueryParameters.ReturnGeometry Property.