Add Features through Enterprise REST API - Example C# .NET

274
0
03-29-2024 08:02 PM
Labels (1)
CraigSchellenbach
New Contributor

I was looking through the documentation and I was having trouble finding a good example of how to add features through the API to my Workforce assignments. I figured I would put up a post up on how I was able to do get it to work.

Note: I use googles API to return Lat/Long from Addresses. This comes back in WKID 4326 and the hosted service is in Spatial Reference: 102100 or WKID 3857 so I had to convert these coordinates to import.

I found an error in the documentation when I was looking through this doc @ https://doc.arcgis.com/en/workforce/android-phone/help/workforce-schema.htm 

SHAPE

The point location of the assignment.

An x,y coordinate pair.

 

This is incorrect, you need to have a geometry field instead of SHAPE. 

Libraries used

Esri.ArcGISRuntime v200.3.0

Newtonsoft.Json v13.0.3

RestSharp v110.2.0

Code to Convert 4326 to 3857

 

 

 

 

 

 

        //Convert EPSG:4326 WGS 84 to EPSG:3857 WGS 84 / Pseudo-Mercator
        private double[] ConvertTo3857(double[] coords)
        {
            double smRadius = 6378136.98;
            double smRange = smRadius * Math.PI * 2.0;
            double smLonToX = smRange / 360.0;
            double smRadiansOverDegrees = Math.PI / 180.0;

            double[] newCoords = new double[2];

            newCoords[0] = coords[0];
            newCoords[1] = coords[1];

            newCoords[0] *= smLonToX;

            double y = newCoords[1];

            if (y > 86.0)
            {
                newCoords[1] = smRange;
            }
            else if (y < -86.0)
            {
                newCoords[1] = -smRange;
            }
            else
            {
                y *= smRadiansOverDegrees;
                y = Math.Log(Math.Tan(y) + (1.0 / Math.Cos(y)), Math.E);
                newCoords[1] = y * smRadius;
            }

            return newCoords;
        }

 

 

 

 

 

 

 

This is the class to great the object that is then converted to JSON with Newtonsoft.Json. This will have to be bracketed with [ ] once converted to string to import.

 

 

 

 

 

 

    public class Assignments
    {
        public Attributes attributes { get; set; }
        public AttributeGeometry geometry { get; set; }
    }
    public class Attributes
    {
        public string description { get; set; }
        public int priority { get; set; }
        public string assignmenttype { get; set; }
        public string workorderid { get; set; }
        public long duedate { get; set; }
        public string location { get; set; }
        public string dispatcherid { get; set; }
        public int status { get; set; }

    }
    public class AttributeGeometry
    {
        public double x { get; set; }
        public double y { get; set; }
    }

 

 

 

 

 

 

 

This class holds the result from importing and will give you the objectID if you need it for further in your code.

 

 

 

 

 

 

    public class AddFeaturesResult
    {
        public Addresult[] addResults { get; set; }
    }

    public class Addresult
    {
        public bool success { get; set; }
        public string globalId { get; set; }
        public int objectId { get; set; }
    }

 

 

 

 

 

 

 

This is calls the portal. I pass in the Service name and the completed JSON String that will be inserted. responseObject has the response.

 

 

 

 

 

 

public async Task UpdateCSUAssignments(string service, string assignment)
{
    string ServiceUrl = @"https://enterpriseUrl/server/rest/services/Hosted/" + service + @"/FeatureServer/0/addFeatures"; //Layer 0

  // generate an ArcGISTokenCredential using input from the user (username and password)
           var cred = await Esri.ArcGISRuntime.Security.AuthenticationManager.Current.GenerateCredentialAsync(
                                                           new Uri("https://enterpriseUrl/portal/sharing/rest/generateToken"),
                                                           "name",
                                                           "password") as ArcGISTokenCredential;

           //Build POST request
           var client = new RestClient(ServiceUrl);
           var request = new RestRequest(ServiceUrl, Method.Post);

           //Add Parameters
           request.AddParameter("token",cred.Token);
           request.AddParameter("f", "json");
           request.AddParameter("features", assignment);
           request.AddParameter("rollbackOnFailure", "false");

           //Execute Request
           var response = client.Execute(request);

           var responseObject = JsonConvert.DeserializeObject<AddFeaturesResult>(response.Content);

           return;
       }

 

 

 

 

 

 

 

 

 

 

 

 

 

//Create Assignment object to hold everything
Assignments assignments = new Assignments();

//Create Attributes object
Attributes attributes = new Attributes(); 
attributes.status = 0;
attributes.assignmenttype = "{34AA8F52-B5A7-4DF9-9F77-169283027D14}";
attributes.location = "Full Address to import";
attributes.dispatcherid = "{AD2B0E54-FA3A-47AE-B639-95A766752E1D}";
attributes.description = "This is a test";
attributes.priority = 1;
attributes.workorderid = "ID that you want tied to Assignment";
attributes.duedate = 1711980000000; //Date that has to be in UTC format

//Create Geometry object in WKID 3857
AttributeGeometry geometry = new AttributeGeometry();
geometry.x = -10072068.9623985;
geometry.y = 4640672.87246465;

//assign attribute object to the assignment object
assignments.attributes = attributes;

//assign geometry to assignment object
assignments.geometry = geometry;

//convert object to JSON string
var json = JsonConvert.SerializeObject(assignments);

//add brackets for importation
json = "[" + json + "]";

//PortalCode is the class that contains all my API calls.
PortalCode portal = new PortalCode();

//call update assignments method
var t = System.Threading.Tasks.Task.Run(async () => { await portal.UpdateCSUAssignments("This is your hosted service ID.", json); });
t.Wait();

 

 

 

 

 

 

 

I hope this helps, I am sure if you change your class objects for other feature services you can use the same code to add features to your services!

 

0 Kudos
0 Replies