ReasonPhrase Not Acceptable HTTPClient C# - c#

I am trying to send a json object with a base4 encoded file to a web api service using the code below
MemoryStream target = new MemoryStream();
q.fileUpload.InputStream.CopyTo(target); //q.fileUpload is an HttpPostedFilebase pdf
var myfile= Convert.ToBase64String(target.ToArray());
var requestbody = new {
filedata = new
{
mimetype = "application/pdf",
basedata = "base64-data=" + myfile
}
};
var jsondata = JsonConvert.SerializeObject(requestbody );
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://web.base.url/");
client.DefaultRequestHeaders.Add("X-API-KEY", "SOMEAPIKEY");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "upload");
request.Content = new StringContent(jsondata, Encoding.UTF8, "application/json");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var responsetask= client.SendAsync(request);
return Json(responsetask);
But i everytime i call this i get a 406 Not Acceptable response. Anyone knows what causes it?

Related

POST result empty after passing a JSON string along with a file

I'm encountering an issue uploading a file (image for this example) along with a JSON string. I am as the client, trying to upload to a webserver. Currently on the website itself, when uploading a file, the payload is this:
------WebKitFormBoundary1A4Toq4hnrayCRu4
Content-Disposition: form-data; name="FileInstance"
{"action":["/public/my_folder"],"fileName":"download_icon.png","fileSize":313,"certification":{"level":"0","Groups":[]}}
------WebKitFormBoundary1A4Toq4hnrayCRu4
Content-Disposition: form-data; name="download_icon.png"; filename="download_icon.png"
Content-Type: image/png
------WebKitFormBoundary1A4Toq4hnrayCRu4--
I am POSTing by 2 separate requests, and each result has a 200 status code, but looking into the result, it's empty and I should be receiving an md5hash of the file uploaded but I am not.
Here is my code:
// Uploading the JSON first
MultipartFormDataContent form = new MultipartFormDataContent();
var boundary = $"----WebKitFormBoundary" + DateTime.Now.Ticks.ToString("x");
form.Headers.Remove("Content-Type");
form.Headers.Add("Content-Type", $"multipart/form-data; boundary={boundary}");
MyFileClass currentFile = new MyFileClass();
currentFile.action = new List<string>() { "/public/my_folder" };
currentFile.filename = Path.GetFileName(Filename);
currentFile.fileSize = Convert.ToInt32(new FileInfo(Filename).Length);
currentFile.certification= new MyFileClass.Certification();
CreateCertification(currentFile.certification);
var json = JsonConvert.SerializeObject(currentFile);
HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = Path.GetFileName(Filename),
FileName = Path.GetFileName(Filename)
};
var response = await myHttpClient.PostAsync(url, form);
var result_str = response.Content.ReadAsStringAsync().Result;
// Uploading the actual file
var stream = new FileStream(Filename, FileMode.Open);
form = new MultipartFormDataContent();
boundary = $"----WebKitFormBoundary" + DateTime.Now.Ticks.ToString("x");
form.Headers.Remove("Content-Type");
form.Headers.Add("Content-Type", $"multipart/form-data; boundary={boundary}");
content = new StreamContent(stream);
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "FileInstance"
};
content = new StreamContent(stream);
form.Add(content, Path.GetFileNameWithoutExtension(Filename));
response = await myHttpClient.PostAsync(url, form);
result_str = response.Content.ReadAsStringAsync().Result;
Edit 1: This is how httpclient is defined:
string password = SecureStringExtensions.ToUnsecuredString(Password);
var credCache = new CredentialCache
{
{
new Uri(url), "Basic", new NetworkCredential(Username, password)
}
};
var myHttpClient = new HttpClient(new HttpClientHandler() { Credentials = credCache });
myHttpClient.DefaultRequestHeaders.Add("Connection", "keep-alive");
myHttpClient.Timeout = Timeout.InfiniteTimeSpan;
I was trying different methods of POSTing which didn't work. Now I found a solution, where I removed editing the boundary and ContentType, and straight forward added the file and JSON at the same time to MultipartFormDataContent and it worked fine.
MyFileClass currentFile = new MyFileClass();
currentFile.action = new List<string>() { "/public/my_folder" };
currentFile.filename = Path.GetFileName(Filename);
currentFile.fileSize = Convert.ToInt32(new FileInfo(Filename).Length);
currentFile.certification= new MyFileClass.Certification();
CreateCertification(currentFile.certification);
var json = JsonConvert.SerializeObject(currentFile);
var formContent = new MultipartFormDataContent
{
{ new StringContent(json, Encoding.UTF8, "application/json") },
{ new StreamContent(new MemoryStream(File.ReadAllBytes(Filename))), Path.GetFileName(Filename) ,Path.GetFileName(Filename)}
};
var response = await myHttpClient.PostAsync(url, formContent);
string stringContent = await response.Content.ReadAsStringAsync();
Where Filename is the absolute path of the file itself.

Httpclient multipart/form-data pust image

I am trying to send a Put request with binary file to upload to the server, using Httpclient.SendAsync or Httpclient.PutAsync. But all i got is 400 bad request in server response. Here is the code
private static HttpResponseMessage Upload()
{
var apiUri = string.Format(url);
string url = (url);
var message = new HttpRequestMessage();
message.RequestUri = new Uri(apiUri);
message.Method = HttpMethod.Put;
var fileObj = Images.ChooseImageAndToInfoObject();
using (var client = new HttpClient())
using (var content = new MultipartFormDataContent())
{
var filestream = new FileStream(fileObj.filePath, FileMode.Open);
content.Add(new StreamContent(filestream), fileObj.fileName, fileObj.fileNameWithExtension);
content.Add(new StringContent("file"), "withName");
content.Add(new StringContent("string"), "fileName");
content.Add(new StringContent("image/*"), "mimeType");
message.Content = content;
message.Headers.Add("Authorization", MyToken);
// var res = client.SendAsync(message).Result;
var response = client.PutAsync(url, content).Result;
return response;
}
Hope for you, guys
Is it necessary to send the filename and mimetype via multipart-formdata? If not try to send the data as StreamContent and set the filename and mime type via the content header:
private static HttpResponseMessage Upload()
{
var apiUri = string.Format(url);
string url = (url);
var message = new HttpRequestMessage();
message.RequestUri = new Uri(apiUri);
message.Method = HttpMethod.Put;
var fileObj = Images.ChooseImageAndToInfoObject();
using (var client = new HttpClient())
var filestream = new FileStream(fileObj.filePath, FileMode.Open);
var content = new StreamContent(filestream);
content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(fileObj.filePath));
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "\"files\"",
FileName = "\"" + fileName + "\""
};
message.Content = content;
message.Headers.Add("Authorization", MyToken);
// var res = client.SendAsync(message).Result;
var response = client.PutAsync(url, content).Result;
return response;
Send the content via PUT if you set the file to a specific id or via Post:
var response = client.PostAsync(url, content).Result;

How to send a json file with HttpClient in C#?

I'm trying send a JSON file with postman and it's working. But when I'm trying to send the same contents via HttpClient it's not working.
System.IO.File.WriteAllText(dirName + "\\importproduct.json", jsonitems);
var fileByteArray = File.ReadAllBytes(dirName + "\\importproduct.json");
using (var _client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(fileByteArray)), "file");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
var response = _client.PostAsJsonAsync(url, content).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
}
PostMan:
Instead of using PostAsJsonAsync(); method you should use PostAsync(); So your code should be looking something like that
using (var _client = new HttpClient())
{
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(fileByteArray)), "file");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
var response = _client.PostAsync(url, content).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
}
PostAsJsonAsync method is a generic method, it expects as the second parameter the object that will be serialized and sent in the POST body.
var obj = JsonConvert.DeserializeObject<SomeModelClass>(jsonString);
var response = await _client.PostAsJsonAsync(url, obj).Result;
This is based on efecetir's post above. It works for me. BTW, I also upvoted his post.
My issue was I needed to set the content type at the content-based level.
var fileByteArray = File.ReadAllBytes(filePath);
HttpContent bytesContent = new ByteArrayContent(fileByteArray);
using (var httpClient = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
var RequestUri = new Uri($"http://whatever.com/");
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
formData.Headers.Add("super-secret-key", "blah");
bytesContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
//httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); //("multipart/form-data")); // Not needed
formData.Add(bytesContent, "file", "blah.json");
var response = httpClient.PostAsync(RequestUri, formData).Result;
return await HandleResponse(response);
}
Thanks for your comments.
I fixed it and convert my codes as below. Now it's working and much more clean.
HttpContent bytesContent = new ByteArrayContent(fileByteArray);
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer_token.id_token);
formData.Add(bytesContent, "file", "importproduct.json");
var response = client.PostAsync(url, formData).Result;
var result = response.Content.ReadAsStringAsync().Result;
}
Here's code I'm using to post form information and a file
using (var httpClient = new HttpClient())
{
var surveyBytes = ConvertToByteArray(surveyResponse);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var byteArrayContent = new ByteArrayContent(surveyBytes);
byteArrayContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/csv");
var url = $"{firmInfo.ServiceUrl}/product/api/products/import";
var response = await httpClient.PostAsync(url , new MultipartFormDataContent
{
{byteArrayContent, "\"file\"", dirName + "\\importproduct.json"}
});
return response;
}
This is for .net 4.5.

Can't get body data on server using C# code

I'm trying to send a json content inside the body. But unfortunately, I don't get the data in the server. Same data is received using postman tool.
Here is the code I'm running
private string callAPI(string function, string content)
{
using (var httpClient = new HttpClient())
{
string url = function;
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", txt_sessionKey.Text);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
httpClient.BaseAddress = new Uri(baseUrlV2);
var json = new StringContent(content, Encoding.UTF8, "application/json");
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Put,
RequestUri = new Uri(baseUrlV2+function),
Content = json
};
HttpContent contentRes = httpClient.SendAsync(request).Result.Content;
return contentRes.ReadAsStringAsync().Result;
}
}
What am I missing here?

How to send a file and form data with HttpClient in C#

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)
{
}
}

Categories