0

In my xamarin forms. I am trying to send multiple images and files using mulipart-formdata.The API team work on back end gave me this structure.

enter image description here

As you can see there is a parameter called "notification_files" which will send images and files selected using Media.Plugin and filepicker plugin in my app. I know how to send data in normal way. But how can I send these formadata using httpclient in xamarin.forms?The API team gave me their equivalent Restsharp code:

var client = new RestClient("{{api_url}}/MYData");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "bearer {{token}}");
request.AddHeader("Content-Type", "application/json");
request.AlwaysMultipartFormData = true;
request.AddParameter("ids", " [{\"id\":1,\"person_id\":5}]");
request.AddParameter("title", " Test");
request.AddParameter("description", " Test");
request.AddParameter("send_text_message", " true");
request.AddParameter("text_message", " Test");
request.AddParameter("notification_type"," global");
request.AddParameter("my_files", "[
  { 
  \"name\": \"abc.jpg\",
  \"key\": \"1583307983694\"
}
]");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content); 

How can I write this using HttpClient?

What I have tried

try {
                MultipartFormDataContent multiContent = new MultipartFormDataContent();
                foreach (SelectedDocumentModel model in SelectedFileData)
                {
                    byte[] byteArray = Encoding.UTF8.GetBytes(model.Path);
                    MemoryStream stream = new MemoryStream(byteArray);
                    HttpContent fileStreamContent1 = new StreamContent(stream);
                    fileStreamContent1.Headers.ContentDisposition = new
                    System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
                    {
                        Name = model.FileName,
                        FileName = model.FileName
                    };
                    fileStreamContent1.Headers.ContentType = new
                    System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
                    multiContent.Add(fileStreamContent1);
                }

                multiContent.Add(new StringContent(notificationdetails[0]), "title");
                multiContent.Add(new StringContent(notificationdetails[1]), "description");
                multiContent.Add(new StringContent(notificationdetails[3]), "type");
                multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
                multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
                multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
                multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");

                HttpClient client = new HttpClient();
                client.DefaultRequestHeaders.Authorization =
                new AuthenticationHeaderValue("bearer",Settings.AuthToken);          
                var response = await client.PostAsync(url, multiContent);
                var responsestr = response.Content.ReadAsStringAsync().Result;
                await DisplayAlert("Result", responsestr.ToString(), "ok");


            }
            catch (Exception ex)
            {
                await DisplayAlert("Result", ex.Message.ToString(), "ok");
            }

DataManager is my observable collection contains images and files selected.

Selecting image using media.plugin and allocating to my observable collection

var Filename = Path.GetFileName(file.Path);
                            var FilePath = file.Path;
                            var newList = new SelectedDocumentModel()
                            {
                                FileName = Filename,
                                SelectedImage = imageSource,
                                IsLoadingVisible = false,
                                Path = FilePath
                            };
                            DataManager.Add(newList);

Any help is appreicted.

Anand
  • 1,866
  • 3
  • 26
  • 49
  • Did you try to send those images in byte[] format with valid key-value. Inside the for loop add those imagepath and name. I achieved using data with single image upload in multipart; byte[] byteImageFile = ImageFileToByteArray(imagePath); multiForm.Add(new ByteArrayContent(byteImageFile, 0, byteImageFile.Count()), "Your-Key", imagename); – Prasanth Mar 17 '20 at 06:15
  • @Prasanth Bro I didnt get it – Anand Mar 17 '20 at 06:19
  • As per my understand, you want to upload those images in "notification_files" key. So could you try the above code, after - multiContent.Add(new StringContent(notificationdetails[9]), "notification_type"); line – Prasanth Mar 17 '20 at 06:22
  • Try the similar way; multiContent.Add(new StringContent(notificationdetails[9]), "notification_type"); byte[] byteImageFile = ImageFileToByteArray(imagePath); multiContent.Add(new ByteArrayContent(byteImageFile, 0, byteImageFile.Count()), "notification_files", imagename); Anyway you already have the image path and its name – Prasanth Mar 17 '20 at 06:25
  • @Prasanth Bro the issue is, I need to upload multiple images. – Anand Mar 17 '20 at 06:26
  • Collect all those imagename and imagepath in a List first, then in the "MultipartFormDataContent", identify using "key as notification_files". If it notification_files, then add the above code in for-loop statement by adding – Prasanth Mar 17 '20 at 06:33
  • @Prasanth Bro sorry for asking. Could you help me to write that? – Anand Mar 17 '20 at 06:34
  • Actually I have experienced in uploading single image with other data using Multipart in Xamarin.Forms. based on the idea only I am suggested. For review https://stackoverflow.com/questions/39866676/retrofit-uploading-multiple-images-to-a-single-key – Prasanth Mar 17 '20 at 06:38
  • @AndroDevil If you want to uploading multiple images, I suggest you can **Plugin.FileUploader** – Cherry Bu - MSFT Mar 18 '20 at 05:55
  • @CherryBu-MSFT Bro. I have some other values apart from images and files like in the postman. Can you help me with that? – Anand Mar 18 '20 at 06:04
  • @Prasanth Bro can you help me to write that loop? I stucked. – Anand Mar 20 '20 at 06:44

1 Answers1

1

I done it like this

MultipartFormDataContent multiContent = new MultipartFormDataContent();
            multiContent.Headers.ContentType.MediaType = "multipart/form-data";
            foreach (SelectedDocumentModel model in SelectedFileData)
            {                 
                var upfilebytes = File.ReadAllBytes(model.Path);
                multiContent.Add(new ByteArrayContent(upfilebytes, 0, upfilebytes.Count()), "notification_files", model.FileName);                        
            }
            multiContent.Add(new StringContent(notificationdetails[0]), "title");
            multiContent.Add(new StringContent(notificationdetails[1]), "description");
            multiContent.Add(new StringContent(notificationdetails[3]), "type");
            multiContent.Add(new StringContent(notificationdetails[7]), "send_text_message");
            multiContent.Add(new StringContent(notificationdetails[2]), "text_message");
            multiContent.Add(new StringContent(notificationdetails[8]), "send_email");
            multiContent.Add(new StringContent(notificationdetails[9]), "notification_type");

            HttpClient client = new HttpClient();                         
            client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("bearer",Settings.AuthToken);         
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Anand
  • 1,866
  • 3
  • 26
  • 49