0

In my xamarin.forms app. I am using Media.plugin to select images from gallery and camera.And also file picker plugin to select files like pdf,jpg etc from file manager.User can select multiple images and files and It will store in an observable collection.In this observable collection I have the path of images as well as files. Where I am stuck is I want to send these data to rest API by using multipart/form data.How can I send these multiple files to the server? Any help is appreciated.

My ObservableCollection

  public ObservableCollection<SelectedDocumentModel> DataManager
        {
            get
            {
                return _selectedfile ?? (_selectedfile = new ObservableCollection<SelectedDocumentModel>());
            }
        }

My Data Model

   public class SelectedDocumentModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }



        public string FileName { get; set; }
        public string Path { get; set; }
        public ImageSource SelectedImage { get; set; }
        public object Tasks { get; internal set; }

        private bool isLoadingVisible = false;
        public bool IsLoadingVisible
        {

            get
            {
                return isLoadingVisible;
            }

            set
            {
                if (value != null)
                {
                    isLoadingVisible = value;
                    NotifyPropertyChanged("IsLoadingVisible");
                }
            }
        }     
    }

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);

Selecting file from file manager using filepicker plugin and assign to observablecollection

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

EDIT

This is what I should do using httpclient.Currently these are written using RestSharp.

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);

What I have done by the way suggested by Lucas Zhang - MSFT.

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");
            }

unfortunately it not working.It not sending the data as I intend.

How can I upload each files as multipart/formdata on a button click.?Any help is appriciated.

1 Answer 1

4

You could use MultipartFormDataContent to add multiple images,and use ContentDispositionHeaderValue.Parameters to add the values of your Data.

Usage

var fileStream = pickedFile.GetStream();
var newList = new SelectedDocumentModel()
                                {
                                    FileName = filename,
                                    SelectedImage = imageSource,
                                    IsLoadingVisible = false,
                                    Path= FilePath,
                                    Data = fileStream ,
                                };

MultipartFormDataContent multiContent = new MultipartFormDataContent();


foreach(var SelectedDocumentModel model in DataManager)
{
  HttpContent fileStreamContent1 = new StreamContent(model.Data);
  fileStreamContent1.Headers.ContentDisposition = new 
  System.Net.Http.Headers.ContentDispositionHeaderValue("form-data") 
  {
     Name = "File", 
     FileName = "xxx.jpg" 
  };
  fileStreamContent1.Headers.ContentType = new 
  System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
  multiContent.Add(fileStreamContent1);


  multiContent.Add(new StringContent(model.Title), "model.Title");
  multiContent.Add(new StringContent(model.Description), "model.Description");
  multiContent.Add(new StringContent(model.Detail), "model.Detail");  
}

// Send (url = url of api) ,use httpclient
var response = await client.PostAsync(url, multiContent);

Sign up to request clarification or add additional context in comments.

11 Comments

Is it possible to upload these without pluign? Because I have some other values need to be pass along with this api request like some title, description. and some ids etc..
Don't forget to accept the answer if it helps you :)
hi bro sorry for not responding back. I am getting error at fileStreamContent1. It says it is null
Or you could upload them in a loop .
Bro. In my edited question, I would like send just like the restsharp code by using Httpclient. What should be the changes I do?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.