I'm trying to post an image to my server using httpclient on Monodroid.
The server-code is ok, infact using Postman all goes well.
This is my code:
var req = new HttpRequestMessage (System.Net.Http.HttpMethod.Post, "http://192.168.0.50:2345/homo");
var content = new MultipartFormDataContent ();
var imageContent = new StreamContent (new FileStream ("my_path.jpg", FileMode.Open, FileAccess.Read, FileShare.Read));
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse ("image/jpeg");
content.Add (imageContent, "image", "image.jpg");
req.Content = content;
await client.SendAsync (req);
When I execute this code, on the server side I get this image:
So, like you can see, something comes... but it is not the complete file.
Can you help me?
Thanks a lot!
HttpClient buffers 64k, which probably equals to the data that is shown on the other side. To have it send the file in chunks do something like:
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
var content = new MultipartFormDataContent ();
var imageContent = new StreamContent (new FileStream ("my_path.jpg", FileMode.Open, FileAccess.Read, FileShare.Read));
imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse ("image/jpeg");
content.Add(imageContent, "image", "image.jpg");
await httpClient.PostAsync(url, content);
However, you don't need the multipart if you are only sending one image...
Related
Title says it all. I need to send an image through the body of a PUT request. This is the code I currently have.
static class Request
{
private readonly static HttpClient client = new HttpClient();
public static async Task<UploadRequest> Upload(string uri, string path)
{
FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
StreamContent streamContent = new StreamContent(fileStream);
MultipartContent content = new MultipartContent();
content.Add(streamContent);
Debug.WriteLine("Making a PUT request");
var response = await client.PutAsync(uri, content);
var result = await response.Content.ReadAsStringAsync();
var deserializedResult = JsonConvert.DeserializeObject<UploadRequest>(result);
fileStream.Close();
Debug.WriteLine("Request made, returning result");
return deserializedResult;
}
}
Instead of using MultipartContent I instead passed in streamContent directly into client.PutAsync like so.
FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read);
StreamContent streamContent = new StreamContent(fileStream);
Debug.WriteLine("Making a PUT request");
var response = await client.PutAsync(uri, streamContent);
However they both produce the same error on my api. Which is "message": "You did not upload an image.". I've checked the actual content of what I've passed in, in both cases when I passed in MultipartContent or streamContent into PutAsync.
The respective output (in order of which I've mentioned them) is System.Net.Http.MultipartContent and System.Net.Http.StreamContent so what exactly am I passing into the body?
Note
I previously asked the wrong question. This is the appropriate one.
I am trying to send a json POST request and save the file returned. This is my code:
var obj = new {data = "zip", name = "h.zip"};
string objString = JsonConvert.SerializeObject(obj);
StringContent stringContent = new StringContent(objString, Encoding.UTF8, "application/json");
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Post, downloadUrl))
{
var result = await httpClient.PostAsync(downloadUrl, stringContent);
Console.WriteLine(result.StatusCode);
var contentStream = await result.Content.ReadAsStreamAsync();
Console.WriteLine(contentStream); // debugger confirms that there is a file present
using (FileStream stream = new FileStream(#"C:\Users\mainuser\Desktop\downloadtest\file.zip", FileMode.Create, FileAccess.Write, FileShare.None, Int32.MaxValue)){
Console.WriteLine("copying started");
await contentStream.CopyToAsync(stream);
Console.WriteLine("never gets printed");
}
}
}
It successfully creates a file.zip, but it maintains to be 0KB in size. Also, Console.WriteLine("never gets printed"); never executes. What is the correct way of downloading file using HttpClient?
I need to send file to WEB API using HttpClient and using the below code to achieve it. I couldn't figure out why am not revcieving any files in WEB API, but the request hits the APIcontroller.
Client Side Code
var fs = new FileStream(#"C:\SomLocation\ExcelFile.xlsx", FileMode.Open, FileAccess.Read);
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
var client = new HttpClient();
client.BaseAddress = new Uri(GetAPIBaseAddress());
HttpContent content = new StreamContent(ms);
var data = new MultipartFormDataContent();
data.Add(content, "file1");
var response = client.PostAsync(GetImportAPIURL(), data).Result;
In API
System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
foreach(System.Web.HttpPostedFile file in hfc)
{
// do some processing;
}
Any help would be greatly appreciated.
I am putting together a test application using WebApi2 and HttpClient in a win forms app.
I have come accross an issue where my HttpClient request to a WebApi2 controller which returns an HttpResponseMessage doesnt return the ByteArrayContent.
WebApiController Code
[HttpGet]
public HttpResponseMessage DownloadFilePart(string fileName)
{
var path = Server.MapPath("~/App_Data/uploads/" + fileName);
var fileArray = System.IO.File.ReadAllBytes(path);
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(fileArray)
};
response.Content.Headers.ContentType = new MediaTypeHeaderValue(System.Web.MimeMapping.GetMimeMapping(fileName));
response.Content.Headers.ContentLength = fileArray.Length;
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = fileName
};
return response;
}
WinForms Code using HttpClient
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var memoryStream = new MemoryStream();
var stream = await responseMessage.Result.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(stream, 0, stream.Length);
}
}
When the request return from the WebApi and I write the bytes to file all that is written into the file is the actual headers from the WebApi response. Has anyone any ideas what the issue could be here?
Thanks
Your problem is here
httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
HttpCompletionOption.ResponseHeadersRead is summarized as
The operation should complete as soon as a response is available and headers are read. The content is not read yet.
This would explain why you only get the headers in your response.
Either remove it completely or change it to HttpCompletionOption.ResponseContentRead
static async void GetFilePart(string hostrUri)
{
var httpClient = new HttpClient
{
BaseAddress = new Uri(hostrUri)
};
var request = new HttpRequestMessage(HttpMethod.Get, "/Home/DownloadFilePart/?fileName=Test.txt");
var responseMessage = await httpClient.SendAsync(request);
var byteArray = await responseMessage.Content.ReadAsByteArrayAsync();
var fileToWriteTo = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Temp\\Test.txt";
using (var fileStream = new FileStream(fileToWriteTo, FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
fileStream.Write(byteArray, 0, byteArray.Length);
}
}
I'm a little confused about how to properly deserialize gziped Json payload from a HttpClient instance.
So far I'm doing the following, but it seems wrong. At least too complicated. Can't I feed a stream to Jil? Can't the HttpClient unzip the stream?
var client = new HttpClient();
var userEndPoint = new Uri(baseUri, "api/login");
var request = new HttpRequestMessage();
request.RequestUri = userEndPoint;
request.Method = HttpMethod.Get;
var response = _client.SendAsync(request).Result;
var userGzipByteArray = response.Content.ReadAsByteArrayAsync().Result;
var outStream = new MemoryStream();
using (var gzStream = new GZipStream(userGzipByteArray , CompressionMode.Decompress))
{
gzStream.CopyTo(outStream);
}
var userByteArray = outStream.ToArray();
var userJson = userByteArray .ConvertToString();
var user = JSON.Deserialize<User>(userJson , Jil.Options.ISO8601PrettyPrintIncludeInherited);
You can use the AutomaticDecompression flag for this. See Does .NET's HttpWebResponse uncompress automatically GZiped and Deflated responses?