How to send a json file with HttpClient in C#? - 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.

Related

Pass Files in C# HttpClient Post request

I am writing code in C# to consume POST API that accepts form-body with the following parameters.
Files[Array] (User can send multiple files in request)
TemplateId[Int]
Also, I need to pass the bearer AuthToken as a header in the HTTP client Post Request.
I need some help writing the HTTP request with the above form data.
using (var client = new HttpClient())
{
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, $" {_apiBaseUri}/{route}");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue($"Bearer {authToken}");
var pdfFiles = Directory.GetFiles($"C:\\files", "*.pdf");
foreach (var filename in pdfFiles)
{
// create array[] of each File and add them to the form data request
}
// Add TemplateId in the form data request
}
postman request
swagger request
you can add files with 'MultipartFormDataContent'.
private static async Task UploadSampleFile()
{
var client = new HttpClient
{
BaseAddress = new("https://localhost:5001")
};
await using var stream = System.IO.File.OpenRead("./Test.txt");
using var request = new HttpRequestMessage(HttpMethod.Post, "file");
using var content = new MultipartFormDataContent
{
{ new StreamContent(stream), "file", "Test.txt" }
};
request.Content = content;
await client.SendAsync(request);
}
for more: https://brokul.dev/sending-files-and-additional-data-using-httpclient-in-net-core
The Below Code change worked for me,
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), _apiBaseUri))
{
request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {authToken}");
var pdfFiles = Directory.GetFiles($"C:\\test", "*.pdf");
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new StringContent("100"), "templateId");
foreach (var filename in pdfFiles)
{
multipartContent.Add(new ByteArrayContent(File.ReadAllBytes(filename)), "files", Path.GetFileName(filename));
}
request.Content = multipartContent;
var response = await httpClient.SendAsync(request);
}
}

Postman form-data: How to program it inside a HttpRequestMessage?

I am doing a request through postman to a specific url but I set the form-data type in order to get data to the site like this:
Now I want to program this request inside C# but everything I tried so far is returning a 400 Bad Request response. This is what I tried:
public async Task<CheckAccessTokenModel> CheckAccessTokenAsync(string accessToken)
{
string uriString = "someurl";
var uri = new Uri(uriString);
try
{
using(var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = uri
};
var ClientId = ConfigurationAccessor.Configuration["WebCredentials:ClientId"];
var Secret = ConfigurationAccessor.Configuration["WebCredentials:Secret"];
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{ClientId}:{Secret}"));
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
MultipartFormDataContent content = new MultipartFormDataContent();
content.Add(new StringContent("token"), accessToken);
request.Content = content;
var response = await httpClient.SendAsync(request);
var checkTokenResponseData = await response.Content.ReadAsStringAsync();
//return new CheckAccessTokenModel { Active = true, Exp = 1647431224233 };
return JsonConvert.DeserializeObject<CheckAccessTokenModel>(checkTokenResponseData);
}
}
catch
{
return null;
}
}
I am doing it with the MultipartFormDataContent Object as suggested by many others here but it still won't work.
What can be the problem here?
EDIT: Wrong picture replaced
You can simply
request.Content = new StringContent($"token={accessToken}");
With form data I think it's something like this:
var data = new Dictionary<string, string>
{
{"token", acccessToken}
};
using var content = new FormUrlEncodedContent(data);
request.Content = content;

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;

ReasonPhrase Not Acceptable HTTPClient 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?

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