Reputation: 1959
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.
Upvotes: 0
Views: 2190
Reputation: 18861
You could use MultipartFormDataContent to add multiple images,and use ContentDispositionHeaderValue.Parameters to add the values of your Data.
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);
Upvotes: 4