Problem using AddAttachment REST method in C#

4204
7
03-22-2017 12:16 PM
MarvinOconitrillo
New Contributor III

Hi,

I'm trying to attach a file to feature in a Esri Feature Service using the REST methods in a Visual Studio C# program, the feature already exist; so the next step as I understand is to call the "AddAttachment" method and pass the parameters, however I'm getting an error sending the file I want to attach, the error message says the following:

{"error":{"code":500,"message":"com.esri.arcgis.discovery.json.JSONArray cannot be cast to com.esri.arcgis.discovery.json.JSONObject","details":[]}}

The following is the method I'm using to call via POST the AddAttachment method:

string POSTAttachment(string url, string jsonContent,string ruta, string nombre)
{
   try
   {
      var aRespStr = "";

      using (System.Net.WebClient client = new System.Net.WebClient())
      {
         client.Headers["Content-type"] = "application/x-www-form-urlencoded";
         client.Encoding = System.Text.Encoding.UTF8;
         var collection = new System.Collections.Specialized.NameValueCollection();
         collection.Add("f", "json");
         collection.Add("attachment", jsonContent);
         client.UploadFile(ruta, nombre);
         var response = client.UploadValues(url, "POST", collection);
         MemoryStream stream = new MemoryStream(response);
         StreamReader reader = new StreamReader(stream);
         aRespStr = reader.ReadToEnd();
      }

      return aRespStr;
   }
   catch (Exception ex)
   {
      return "";
   }
}

I'm calling the method in this way:


string jsonAttachment = "[{\"attachment\":\"img.jpg\"}]";
string resultadoAttachment = POSTAttachment("http://crdes09:6080/arcgis/rest/services/Servicio_Prueba/Mapa_Control_Vectores_Movil_/FeatureServer/...", jsonAttachment, "C:\\img1.jpg", "img1.jpg");

My doubt is about how to embed the file into the call to the AddAttachment, is something i'm missing to do to solve this message about casting?

I'll really appreciated any help.

0 Kudos
7 Replies
ChrisLavoro
New Contributor

Marvin,

I am also attempting to add an image attachment via C#. 

I keep getting:

{"error":{"code":500,"message":"JSONObject[\"uploadedFilePath\"] not found.","details":[]}}

Where you able to resolve this?

0 Kudos
MarvinOconitrillo
New Contributor III

Hi,


We couldn't resolve the problem with C#, so we did it with a Python script.

0 Kudos
ChrisLavoro
New Contributor

Hello,

Thanks, yes I also got to work with calling a Python script from C#.

My colleague also got it to work directly with C# using the Restsharp plugin with combination of client wrapper around the request, making sure that the type in Restsharp was set to POST.

0 Kudos
TakahiroKAMIYA
Esri Contributor

Hello,

I am also suffering from the same thing in C #.
Either code did not work.

// code example 1 
var service_Url = "https://services5.arcgis.com/HzGpeRqGvs5TMkVr/arcgis/rest/services/SampleData_LatLon/FeatureServer/0...";
var featureId = "1";
string request = String.Format(@"{0}/{1}/addAttachment", service_Url, featureId);

var fileName = @"D:\ArcGIS Runtime SDK for .NET v100.2\data\2017-12-21_1447.png";

var content = new MultipartFormDataContent();

var fileContent = new StreamContent(File.OpenRead(fileName));

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName)
};

content.Add(fileContent);

var httpClient = new HttpClient();
HttpResponseMessage response = httpClient.PostAsync(request, content).Result;

// code example 2
var fileContent = new StreamContent(File.OpenRead(fileName));

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName)
};
 
using (var client = new HttpClient())
{
    var req = new HttpRequestMessage();
    req.RequestUri = new Uri("http://services5.arcgis.com/HzGpeRqGvs5TMkVr/arcgis/rest/services/SampleData_LatLon/FeatureServer/0/...");
    req.Method = HttpMethod.Post;
    req.Content = fileContent;
    req.Content.Headers.Add("Content-Type", "image/png");

    await client.SendAsync(req);
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

https://developers.arcgis.com/rest/services-reference/add-attachment.htm

Is it necessary to set the content type, file name, etc. for the 'attachment' parameter?

0 Kudos
ChrisLavoro
New Contributor

Hello,

Try using the RestSharp plugin in C# to do the POST.

0 Kudos
JeanPIERRON
New Contributor

Hi,

This thread is pretty old now, but if anyone is having this issue today, i managed to get it to work this way - given i received the attachment as IFormFile - passing to the httpClient a MultipartFormDataContent containing the token and output format as StringContent, et my attachment as ByteArrayContent :

var memoryStream = new MemoryStream();
Attachment.CopyTo(memoryStream);
var byteArrayContent = new ByteArrayContent(memoryStream.ToArray());
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse(Attachment.ContentType);

var httpContent = new MultipartFormDataContent
{
   {new StringContent(Token), "\"token\""},
   {new StringContent(OutputFormat), "\"f\""},
   {byteArrayContent, "\"attachment\"", Attachment.FileName}
};

var res = await httpClient.PostAsync(addAttachmentUrl, httpContent);
0 Kudos
ShaggyHiker
New Contributor

This is a sufficiently complicated subject that I felt I might add another solution that worked for me, in case anybody stumbles across this thread with the same question. The solution is in VB.NET, but it can readily be converted to C#. I'll try to explain it a bit along the way, because it's pretty horrible.

I was attempting to include a pdf attachment, but that likely makes little difference. 

The key was to make a FormFile. There are many ways to open a file in a .NET desktop application, and this is surely the worst way I've ever seen, but nothing simpler seemed to work. I believe that was because I wasn't able to get the content type or the file name into the ByteArrayContent by any other means.

Dim cntent As New MultipartFormDataContent
                Dim fStream As New FileStream(flNm, FileMode.Open)
                Dim fFile As New FormFile(fStream, 0, fStream.Length, "", fileOnly)

                Dim mStream As New MemoryStream
                fFile.CopyTo(mStream)
                Dim bytContent As New ByteArrayContent(mStream.ToArray)
                bytContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf")

                cntent.Add(New StringContent(token), "token")
                cntent.Add(New StringContent("json"), "f")
                cntent.Add(bytContent, "attachment", fileOnly)

               response = Await client.PostAsync(yourURLHere & /addAttachment", cntent)
                    If response.IsSuccessStatusCode Then
                        result = Await response.Content.ReadAsStringAsync
                        'JUST FOR TESTING PURPOSE. Check for good response.
                        result = result 
                    End If
                End If

 I  

0 Kudos