I am currently trying to POST some data to server to create user profile. The body of RESTful POST has selected image and also other fields.
I managed to POST it using Postman. However, I am trying to figure out how to do it using C#. I attempted but it seems that server returns status 500 without much useful message.
Please refer attachments on how i POST to server and some C# code on how I attempted to POST it. Appreciate help on how to fix my C# code to make it work.
C# code:
if (!string.IsNullOrEmpty(baseUrl) && !string.IsNullOrEmpty(apiKey))
{
var fullUrl = baseUrl + "/user_profiles";
using (var httpClient = new HttpClient())
{
//httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", apiKey);
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiKey);
var boundary = "Upload----" + DateTime.Now.Ticks.ToString();
using (var content = new MultipartFormDataContent(boundary))
{
try
{
var name = string.IsNullOrEmpty(userRegistration.Name) ? "" : userRegistration.Name;
var city = string.IsNullOrEmpty(userRegistration.City) ? "" : userRegistration.City.ToUpper();
var phone = string.IsNullOrEmpty(userRegistration.Mobile) ? "" : userRegistration.Mobile;
phone = phone.Replace(" ", ""); //remove empty string in between and at edges
phone = phone.StartsWith("+") ? phone : "+" + phone;
var address = string.IsNullOrEmpty(userRegistration.CompanyAddress) ? "Unspecified" : userRegistration.CompanyAddress;
var country = string.IsNullOrEmpty(userRegistration.Country) ? "" : userRegistration.Country.ToUpper();
var email = string.IsNullOrEmpty(userRegistration.Email) ? "" : userRegistration.Email;
var isContractor = userRegistration.IsRegisteredAsContractor.ToString();
var category = string.IsNullOrEmpty(userRegistration.Category) ? "" : userRegistration.Category;
var companyName = string.IsNullOrEmpty(userRegistration.CompanyName) ? "" : userRegistration.CompanyName;
var companyAddress = string.IsNullOrEmpty(userRegistration.CompanyAddress) ? "" : userRegistration.CompanyAddress;
//TEST
//var body = new
//{
// city,
// phone,
// address,
// country,
// email,
// name,
// identifier_for_vendor = localId,
// is_contractor = isContractor,
// work_categories = category,
// company_name = companyName,
// company_address = companyAddress
//};
//var bodyStr = JsonConvert.SerializeObject(body);
//var stringContent = new StringContent(bodyStr, Encoding.UTF8, "application/json");
//content.Add(stringContent);
//response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
//TEST
content.Add(new StringContent(name, Encoding.UTF8, "text/plain"), "name");
content.Add(new StringContent(city, Encoding.UTF8, "text/plain"), "city");
content.Add(new StringContent(phone, Encoding.UTF8, "text/plain"), "phone");
content.Add(new StringContent(companyAddress, Encoding.UTF8, "text/plain"), "address");
content.Add(new StringContent(country, Encoding.UTF8, "text/plain"), "country");
content.Add(new StringContent(email, Encoding.UTF8, "text/plain"), "email");
content.Add(new StringContent(localId, Encoding.UTF8, "text/plain"), "identifier_for_vendor");
content.Add(new StringContent(isContractor, Encoding.UTF8, "text/plain"), "is_contractor");
content.Add(new StringContent(category, Encoding.UTF8, "text/plain"), "work_categories");
content.Add(new StringContent(companyName, Encoding.UTF8, "text/plain"), "company_name");
content.Add(new StringContent(companyAddress, Encoding.UTF8, "text/plain"), "company_address");
if (!string.IsNullOrEmpty(userRegistration.ProfileImagePath) && File.Exists(userRegistration.ProfileImagePath))
{
using (var stream = File.OpenRead(userRegistration.ProfileImagePath))
{
//stream.Seek(0, SeekOrigin.Begin);
var fileName = Guid.NewGuid().ToString() + ".jpg";
content.Add(new StreamContent(stream), "image", fileName);
response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
}
}
else
{
response = await httpClient.PostAsync(fullUrl, content).ConfigureAwait(false);
}
}
catch (Exception ex)
{
}
}
}
}
When you use File.OpenRead, It will return a File Stream (Bytes)
You need to convert it to Base64 which is the preferred way of sending images over REST.
base64Image = System.Convert.ToBase64String(stream);
After that, you will need to convert it back on your backend and store it where ever you want.
Also, I wouldn't recommend using FormDataContent to send the data since it has some size limitations.
I recommend using JObjectand adding what you want to send as JProperty.
Uri postURL = new Uri(Constants.RestUrl + "/NewReservation");
HttpClient client = new HttpClient();
TimeSpan timeout = new TimeSpan(0, 0, 20);
client.Timeout = timeout;
var UserData = AccountCheck.CurrentUserData();
JObject RequestData = new JObject(
new JProperty("apiKey", UserData.ApiKey),
new JProperty("customerID", UserData.CustomerId.ToString()),
new JProperty("containerIDs", NewReservationRequest.ContainerIDs),
new JProperty("containersQuantities", NewReservationRequest.ContainerQuantities),
new JProperty("location", NewReservationRequest.Location),
new JProperty("image", NewReservationRequest.ImageBlob),
new JProperty("dateFrom", NewReservationRequest.StartDate.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)),
new JProperty("dateTo", NewReservationRequest.StartDate.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)),
new JProperty("expectedTime",NewReservationRequest.ExpectedTime),
new JProperty("remarks", UserRemarks)
);
var RequestDataString = new StringContent(RequestData.ToString(), Encoding.UTF8, "application/json");
HttpResponseMessage responsePost = await client.PostAsync(postURL, RequestDataString);
string response = await responsePost.Content.ReadAsStringAsync();
After that , you will need to parse the json response.
reply to this answer if you need more help
Related
How can I send a file and form data with the HttpClient?
I have two ways to send a file or form data. But I want to send both like an HTML form. How can I do that? Thanks.
This is my code:
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
var client = new HttpClient();
var requestContent = new MultipartFormDataContent();
filename = openFileDialog1.FileName;
array = File.ReadAllBytes(filename);
var imageContent = new ByteArrayContent(array);
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("audio/*");
requestContent.Add(imageContent, "audio", "audio.wav");
var values = new Dictionary<string, string>
{
{ "token", "b53b99534a137a71513548091271c44c" },
};
var content = new FormUrlEncodedContent(values);
requestContent.Add(content);
var response = await client.PostAsync("localhost", requestContent);
var responseString = await response.Content.ReadAsStringAsync();
txtbox.Text = responseString.ToString();
}
Here's code I'm using to post form information and a csv file
using (var httpClient = new HttpClient())
{
var surveyBytes = ConvertToByteArray(surveyResponse);
httpClient.DefaultRequestHeaders.Add("X-API-TOKEN", _apiToken);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var byteArrayContent = new ByteArrayContent(surveyBytes);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
var response = await httpClient.PostAsync(_importUrl, new MultipartFormDataContent
{
{new StringContent(surveyId), "\"surveyId\""},
{byteArrayContent, "\"file\"", "\"feedback.csv\""}
});
return response;
}
This is for .net 4.5.
Note the \" in the MultipartFormDataContent. There is a bug in MultipartFormDataContent.
In 4.5.1 MultipartFormDataContent wraps the data with the correct quotes.
Update: This link to the bug no longer works since the have retired Microsoft Connect.
Here's code I'm using a method to send file and data from console to API
static async Task uploaddocAsync()
{
MultipartFormDataContent form = new MultipartFormDataContent();
Dictionary<string, string> parameters = new Dictionary<string, string>();
//parameters.Add("username", user.Username);
//parameters.Add("FullName", FullName);
HttpContent DictionaryItems = new FormUrlEncodedContent(parameters);
form.Add(DictionaryItems, "model");
try
{
var stream = new FileStream(#"D:\10th.jpeg", FileMode.Open);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(#"http:\\xyz.in");
HttpContent content = new StringContent("");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "uploadedFile1",
FileName = "uploadedFile1"
};
content = new StreamContent(stream);
form.Add(content, "uploadedFile1");
client.DefaultRequestHeaders.Add("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.dsfdsfdsfdsfsdfkhjhjkhjk.vD056hXETFMXYxOaLZRwV7Ny1vj-tZySAWq6oybBr2w");
var response = client.PostAsync(#"\api\UploadDocuments\", form).Result;
var k = response.Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
{
}
}
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.
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.
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"));
I need to post a file from asp application to an API
the file will be uploaded through <asp:FileUpload />
in the back end, i will receive the file and send it to Web API method
the web API method will contain the code
var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploadfiles");
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
the asp page will has the code
using (System.IO.Stream fs = fuID.PostedFile.InputStream)
{
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost:5000/path"))
{
request.Headers.TryAddWithoutValidation("Accept", "application/json, text/plain, */*");
request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + AppUserContext.Token);
request.Headers.TryAddWithoutValidation("x-language", "ar");
// Iam Not Sure of this line
request.Content = new StringContent("Content-Disposition:" + base64String, Encoding.UTF8, "multipart/form-data");
var response = httpClient.SendAsync(request).Result;
}
}
}
i need to know how i can send the file in the body of the request what to write in this line
request.Content = new StringContent("Content-Disposition:" + base64String, Encoding.UTF8, "multipart/form-data");
pf is the posted file
then use
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AppUserContext.Token);
client.DefaultRequestHeaders.Add("x-language", "ar");
using (var stream = pf.InputStream)
{
var content = new MultipartFormDataContent();
var file_content = new ByteArrayContent(new StreamContent(stream).ReadAsByteArrayAsync().Result);
file_content.Headers.ContentType = new MediaTypeHeaderValue(pf.ContentType);
file_content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = JsonConvert.SerializeObject(pf.FileName),
};
content.Add(file_content);
var url = "URL Here";
var response = client.PostAsync(url, content).Result;
response.EnsureSuccessStatusCode();
}
}
Can any one explain how can i make POST request to a URL on web with different type of data, in my case i have an image and two string type values to send to a server in PHP.
here what i already have done
var stream = await file.OpenStreamForReadAsync();
var streamcontent = new StreamContent(stream);
streamcontent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "photo",
FileName = file.Name
};
streamcontent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
MultipartFormDataContent multipart = new MultipartFormDataContent();
multipart.Add(streamcontent);
try
{
descContent = mytextbox.Text;
var stringcontent = new StringContent(descContent);
stringcontent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("description", descContent));
multipart.Add(stringcontent);
HttpResponseMessage res = await client.PostAsync(new Uri("http://localhost/web/test/index.php"), multipart);
res.EnsureSuccessStatusCode();
mytextbox.Text = await res.Content.ReadAsStringAsync();
}
catch (HttpRequestException ex)
{
mytextbox.Text = ex.Message;
}
this code will send the image file but not the description(string), i have searched over the internet but I could not find appropriate answer.
here is the PHP code
if (isset($_FILES['photo']))
{
echo $_FILES["photo"]["name"] . "<br>";
}
else
{
echo "Image: Error<br>";
}
if (isset($_POST['description']))
{
echo $_POST['description'];
}
else
{
echo "Text: Error";
}
any response will be highly appreciated.
thank you
I have search a lot and finally got the way out. here is the code
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://www.yourdomain.com");
MultipartFormDataContent form = new MultipartFormDataContent();
HttpContent content = new StringContent("your string type data you want to post");
form.Add(content, "name");
var stream = await file.OpenStreamForReadAsync();
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "image",
FileName = file.Name
};
form.Add(content);
var response = await client.PostAsync("index.php", form);
mytextblock.Text = response.Content.ReadAsStringAsync();
I wrote it on my blog here is the code. :-)
HappyCoding
Upload files with HTTPWebrequest (multipart/form-data)
http://www.paraesthesia.com/archive/2009/12/16/posting-multipartform-data-using-.net-webrequest.aspx/
UPDATE 1
I think I am using incorrect URL, this doc says to use "https://www.googleapis.com/drive/v2/files" & this doc says to use "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart". Though I am getting same 400 bad request.
Can I use Google Drive upload REST API in background uploader class?
I am following this doc from Google Drive to upload files but I am getting 400 - Bad request. What's wrong with my code?
public static async Task UploadFileAsync(Token AuthToken, StorageFile file, DriveFile objFolder)
{
try
{
if (!httpClient.DefaultRequestHeaders.Contains("Authorization"))
{
httpClient.DefaultRequestHeaders.Add("Authorization", AuthToken.TokenType + " " + AuthToken.AccessToken);
}
var JsonMessage = JsonConvert.SerializeObject(objFolder);
/*JsonMessage = {"title":"c4611_sample_explain.pdf","mimeType":"application/pdf","parents":[{"id":"root","kind":"drive#fileLink"}]}*/
var JsonReqMsg = new StringContent(JsonMessage, Encoding.UTF8, "application/json");
var fileBytes = await file.ToBytesAsync();
var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(fileBytes));
form.Add(JsonReqMsg);
form.Headers.ContentType = new MediaTypeHeaderValue("multipart/related");
var UploadReq = await httpClient.PostAsync(new Uri("https://www.googleapis.com/drive/v2/files?uploadType=multipart"), form);
if (UploadReq.IsSuccessStatusCode)
{
var UploadRes = await UploadReq.Content.ReadAsStringAsync();
}
else
{
}
}
catch (Exception ex)
{
}
}
You must use https://www.googleapis.com/upload/drive/v2/files
I have a working sample here (sorry, the JSON string is hard coded):
// Multipart file upload
HttpClient client = new HttpClient();
string uriString = "https://www.googleapis.com/upload/drive/v2/files?key=<your-key>&access_token=<access-token>&uploadType=multipart";
Uri uri = new Uri(uriString);
HttpContent metadataPart = new StringContent(
"{ \"title\" : \"My File\"}",
Encoding.UTF8,
"application/json");
HttpContent mediaPart = new StringContent(
"The naughty bunny ate all the cookies.",
Encoding.UTF8,
"text/plain");
MultipartContent multipartContent = new MultipartContent();
multipartContent.Add(metadataPart);
multipartContent.Add(mediaPart);
HttpResponseMessage response = await client.PostAsync(uri, multipartContent);
string responseString = await response.Content.ReadAsStringAsync();