I have an API which is returning HTTPResponse with Content of type "Stream Content". Now i want to consume this API in another application and download the zip file sent as stream content. Can someone please suggest how can I achieve this in C#?
private HttpResponseMessage GetHttpResponseMessageForConfigFile(Component component)
{
var result = Request.CreateResponse(HttpStatusCode.OK);
component.ConfigData = _configDataService.GetConfigDetail(component.Id).Data;
var mermoryStream = new MemoryStream(component.ConfigData);
result.Content = new StreamContent(mermoryStream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = string.Format("{0}.zip", component.Code)
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return result;
}
In the above, component.ConfigData contains a byte array of zip file.
You download a ZIP file like any other binary file as well:
using (WebClient client = new WebClient())
{
client.DownloadFile(new Uri(url), #"c:\path\to\file.zip");
}
Related
I'm trying to interact with a API that doesn't support multipart/form-data for uploading a file.
I've been able to get this to work with the older WebClient but since it's being deprecated I wanted to utilize the newer HttpClient.
The code I have for WebClient that works with this end point looks like this:
using (WebClient client = new WebClient())
{
byte[] file = File.ReadAllBytes(filePath);
client.Headers.Add("Authorization", apiKey);
client.Headers.Add("Content-Type", "application/pdf");
byte[] rawResponse = client.UploadData(uploadURI.ToString(), file);
string response = System.Text.Encoding.ASCII.GetString(rawResponse);
JsonDocument doc = JsonDocument.Parse(response);
return doc.RootElement.GetProperty("documentId").ToString();
}
I've not found a way to get an equivalent upload to work with HttpClient since it seems to always use multipart.
I think it would look something like this
using var client = new HttpClient();
var file = File.ReadAllBytes(filePath);
var content = new ByteArrayContent(file);
content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
var result = await client.PostAsync(uploadURI.ToString(), content);
result.EnsureSuccessStatusCode();
var response = await result.Content.ReadAsStringAsync();
var doc = JsonDocument.Parse(response);
return doc.RootElement.GetProperty("documentId").ToString();
What speaks against using simply HttpClient's PostAsync method in conjunction with ByteArrayContent?
byte[] fileData = ...;
var payload = new ByteArrayContent(fileData);
payload.Headers.Add("Content-Type", "application/pdf");
myHttpClient.PostAsync(uploadURI, payload);
Im trying to download a PDF file crossing over two API's with a GET Request.
If I go direct to API2 the PDF downloads fine with the below code:
Stream fileStream = File.Open(fileLocation, FileMode.Open);
result.Content = new StreamContent(fileStream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "test.pdf"
};
return result;
However when I throw API1 into the mix things get a little wonky!!
using (System.Net.Http.HttpClient client = new System.Net.Http.HttpClient())
{
var httpRequestMessage = new HttpRequestMessage();
httpRequestMessage.Method = HttpMethod.Get;
httpRequestMessage.RequestUri = new Uri(requestUrl);
HttpResponseMessage response = await client.SendAsync(httpRequestMessage);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
response.Content = new StringContent(content);
response.EnsureSuccessStatusCode();
response.Content.Headers.ContentEncoding.Add("UTF8");
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "test.pdf"
};
return response;
Going direct to API2 produces: %PDF-1.6%âãÏÓ
Going via API2 produces:%PDF-1.6%����
Ive tried changing ContentType and ContentEncoding on API1 with no joy.
Does anything jump out to anyone?
Calling .ReadAsStringAsync on a binary document wont work - you have to call .ReadAsByteArrayAsync.
You also have to use ByteArrayContent instead of StringContent.
not tested
i am trying to download a file (.docx) from asp.net web api.
Since i already have a document in the server i set the path to existing one and then i follow something sugested on stackoverflow and do this:
docDestination is my path.
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(docDestination, FileMode.Open, FileAccess.Read);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
return result;
after that on my client side i try to do this:
.then(response => {
console.log("here lives the response:", response);
var headers = response.headers;
var blob = new Blob([response.body], { type: headers['application/vnd.openxmlformats-officedocument.wordprocessingml.document'] });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "Filename";
link.click();
}
this is what i get on my response
what i get:
any help?
Just add ContentDisposition to your response header with value of attachment and the browser will interpret it as a file that needs to be download
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(docDestination, FileMode.Open,FileAccess.Read);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "document.docx"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
return result;
Take a look in this link for more information in ContentDisposition header
Change return type of your method. You can write method something like this.
public FileResult TestDownload()
{
FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes("YOUR PATH TO DOC"), "application/msword")
{
FileDownloadName = "myFile.docx"
};
return result;
}
In client side, you just need to have a link button. Once you click on the button, file will be downloaded. Just write this line in cshtml file. replace controller name with your controller name.
#Html.ActionLink("Button 1", "TestDownload", "YourCOntroller")
When you have a stream open, you want to return it's content as a file
[HttpGet]
public async Task<FileStreamResult> Stream()
{
var stream = new MemoryStream(System.IO.File.ReadAllBytes("physical path of file"));
var response = File(stream, "Mime Type of file");
return response;
}
You use it when you have a byte array you would like to return as a file
[HttpGet]
public async Task<FileContentResult> Content()
{
var result = new FileContentResult(System.IO.File.ReadAllBytes("physical path of file"), "Mime Type of file")
{
FileDownloadName = "Your FileName"
};
return result;
}
when you have a file on disk and would like to return it's content (you give a path)-------------only in asp.net core
[HttpGet]
public async Task<IActionResult> PhysicalPath()
{
var result = new PhysicalFileResult("physical path of file", "Mime Type of file")
{
FileDownloadName = "Your FileName",
FileName = "physical path of file"
};
return result;
}
I am trying to upload a file to Onedrive using RestSharp and Graph API. Basically I want to upload an Excel file. However, even the file saves, there is problem with the content. I am using:
https://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/item_uploadcontent
using the code:
string newToken = "bearer ourtoken";
var client = new RestClient("https://xxx-my.sharepoint.com/_api/v2.0/"+ oneDrivePath + Path.GetFileName(filePathWithName) + ":/content");
var request = new RestRequest(Method.PUT);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Authorization", newToken);
request.AddHeader("Content-Type", "text/plain");
byte[] sContents;
FileInfo fi = new FileInfo(filePathWithName);
// Disk
FileStream fs = new FileStream(filePathWithName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
sContents = br.ReadBytes((int)fi.Length);
br.Close();
fs.Close();
request.AddBody(Convert.ToBase64String(sContents));
var response = client.Execute(request);
This uploads the file however the XLSX file becomes corrupted.
Basically I need to figure out how to pass the stream to the RestSharp request.
Solved it by changing RestClient to HttpClient.
string newToken = "bearer mytoken"
using (var client = new HttpClient())
{
var url = "https://xxx-my.sharepoint.com/_api/v2.0/" + oneDrivePath + Path.GetFileName(filePathWithName) + ":/content";
client.DefaultRequestHeaders.Add("Authorization", newToken);
byte[] sContents = File.ReadAllBytes(filePathWithName);
var content = new ByteArrayContent(sContents);
var response = client.PutAsync(url, content).Result;
return response;
}
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...