download excel file using web api and angularjs - c#

Front-end
var url = baseUrl+ "/api/Home/DownloadReport";
window.open(url);
Back-end
[HttpGet]
public HttpResponseMessage DownloadReport()
{
var stream = new System.IO.MemoryStream(File.ReadAllBytes(#"C:\Users\mypc\Desktop\Test\5\WebApplication1\Report.xlsx"));
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream);
};
result.Content.Headers.ContentDisposition = new
System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "myworkbook.xlsx"
};
result.Content.Headers.ContentType = new
System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentLength = stream.Length;
return result
}
I am trying to download an excel file using web API and angularjs but when I click the download button it opens a new tab with the message as below but does not download the file can someone suggest to me what is wrong with the code.
StatusCode:200,ReasonPhrase:'OK',Version:1.1,Content:System.Net.Http.ByteArrayContent,Headers:{Content-Type:application/octet-stream Content Disposition:attachment;filename=myworkbook.xlsx}
I know the question has been asked previously but tried many solutions but was not able to solve issue

Front-end
Instead of using window.open, uses this workaround:
var url = baseUrl+ "/api/Home/DownloadReport";
var tmp = document.createElement('A');
tmp.href = url;
tmp.type = 'application/vnd.ms-excel';
tmp.download = 'myworkbook.xlsx';
tmp.click();
Back-end
Try to use application/vnd.ms-excel in the argument of MediaTypeHeaderValue constructor.

Related

How can i save a REST Response to a PDF file? [duplicate]

I have a URL (URL for the live feed from client) which when I hit in browser returns the xml response . I have saved this in text file it`s size is 8 MB.
now my problem is that I need to save this response in xml file on server`s drive. from there I will insert this in database. and request needs to be made using code using http-client or rest-sharp library of c# .net 4.5
I am unsure what should I do for above case. can any body suggest me something
With RestSharp, it's right there in the readme:
var client = new RestClient("http://example.com");
client.DownloadData(request).SaveAs(path);
With HttpClient, it's a bit more involved. Have a look at this blog post.
Another option is Flurl.Http (disclaimer: I'm the author). It uses HttpClient under the hood and provides a fluent interface and lots of convenient helper methods, including:
await "http://example.com".DownloadFileAsync(folderPath, "foo.xml");
Get it on NuGet.
It seems SaveAs was discontinued. You can try this
var client = new RestClient("http://example.com")
byte[] response = client.DownloadData(request);
File.WriteAllBytes(SAVE_PATH, response);
In case you want async version
var request = new RestRequest("/resource/5", Method.GET);
var client = new RestClient("http://example.com");
var response = await client.ExecuteTaskAsync(request);
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception($"Unable to download file");
response.RawBytes.SaveAs(path);
Don't keep the file in memory while reading. Write it directly to the disk.
var tempFile = Path.GetTempFileName();
using var writer = File.OpenWrite(tempFile);
var client = new RestClient(baseUrl);
var request = new RestRequest("Assets/LargeFile.7z");
request.ResponseWriter = responseStream =>
{
using (responseStream)
{
responseStream.CopyTo(writer);
}
};
var response = client.DownloadData(request);
Copied from here https://stackoverflow.com/a/59720610/179017.
Add following NuGet package into the current system
dotnet add package RestSharp
Using Bearer Authentication
// Download file from 3rd party API
[HttpGet("[action]")]
public async Task<IActionResult> Download([FromQuery] string fileUri)
{
// Using rest sharp
RestClient client = new RestClient(fileUri);
client.ClearHandlers();
client.AddHandler("*", () => { return new JsonDeserializer(); });
RestRequest request = new RestRequest(Method.GET);
request.AddParameter("Authorization", string.Format("Bearer " + accessToken),
ParameterType.HttpHeader);
IRestResponse response = await client.ExecuteTaskAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// Read bytes
byte[] fileBytes = response.RawBytes;
var headervalue = response.Headers.FirstOrDefault(x => x.Name == "Content-Disposition")?.Value;
string contentDispositionString = Convert.ToString(headervalue);
ContentDisposition contentDisposition = new ContentDisposition(contentDispositionString);
string fileName = contentDisposition.FileName;
// you can write a own logic for download file on SFTP,Local local system location
//
// If you to return file object then you can use below code
return File(fileBytes, "application/octet-stream", fileName);
}
}
Using Basic Authentication
// Download file from 3rd party API
[HttpGet("[action]")]
public async Task<IActionResult> Download([FromQuery] string fileUri)
{
RestClient client = new RestClient(fileUri)
{
Authenticator = new HttpBasicAuthenticator("your user name", "your password")
};
client.ClearHandlers();
client.AddHandler("*", () => { return new JsonDeserializer(); });
RestRequest request = new RestRequest(Method.GET);
IRestResponse response = await client.ExecuteTaskAsync(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// Read bytes
byte[] fileBytes = response.RawBytes;
var headervalue = response.Headers.FirstOrDefault(x => x.Name == "Content-Disposition")?.Value;
string contentDispositionString = Convert.ToString(headervalue);
ContentDisposition contentDisposition = new ContentDisposition(contentDispositionString);
string fileName = contentDisposition.FileName;
// you can write a own logic for download file on SFTP,Local local system location
//
// If you to return file object then you can use below code
return File(fileBytes, "application/octet-stream", fileName);
}
}

Document uploaded to MS Teams using graph API gets corrupted

I am trying to upload a document to Microsoft Teams using Microsoft Graph (beta version), but the document gets corrupted after a successful upload.
Using Graph, I'm first creating an Group, creating a Team based on the Group, adding some Team Members and finally uploading a document to the default channel.
All works fine except the uploaded document gets corrupted and the Office Online editor is not able to open it. We can however download the file and open in Microsoft Word after correcting the file.
Below is the code that I'm using for document upload->
FileInfo fileInfo =
new FileInfo(#"F:\Projects\TestProjects\MSTeamsSample\MSTeamsSample\Files\Test File.docx");
var bytes = System.IO.File.ReadAllBytes(fileInfo.FullName);
var endpoint = $"https://graph.microsoft.com/beta/groups/{groupId}/drive/items/root:/General/{fileInfo.Name}:/content";
var fileContent = new ByteArrayContent(bytes);
fileContent.Headers.ContentType =
MediaTypeHeaderValue.Parse("application/octet-stream");
var requestContent = new MultipartFormDataContent();
requestContent.Add(fileContent, "File", fileInfo.Name);
var request = new HttpRequestMessage(HttpMethod.Put, endpoint);
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", "<Access Token>");
request.Content = requestContent;
var client = new HttpClient();
var response = client.SendAsync(request).Result;
I tried changing content type to application/vnd.openxmlformats-officedocument.wordprocessingml.document but no luck. I don't understand what could be wrong here. The code is pretty straight forward, based on the this documentation. Any help will be highly appreciated.
Please try this:
var filePath = #"F:\Projects\TestProjects\MSTeamsSample\MSTeamsSample\Files\Test File.docx";
var fileName = Path.GetFileName(filePath);
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
var endpoint = $"https://graph.microsoft.com/beta/groups/{groupId}/drive/items/root:/General/{fileName}:/content";
using (var client = new HttpClient())
{
using (var content = new StreamContent(fileStream))
{
content.Headers.Add("Content-Type", MimeMapping.GetMimeMapping(fileName));
// Construct the PUT message towards the webservice
using (var request = new HttpRequestMessage(HttpMethod.Put, endpoint))
{
request.Content = content;
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.Token);
// Request the response from the webservice
using (var response = await client.SendAsync(request))
{
// Check the response.
}
}
}
}
I am able to see Word document in Microsoft Teams editor.

Upload multiple files using web api in c#

I wanted to make an api call equivalent to the given image (api call made from postman) using WebClient or HttpClient. I want to send a file and a text together in one single api call.
You can save image via api call by HttpClient . here is the code:
Send file to the API
var content = new ByteArrayContent(filedata);
content.Headers.ContentType = new MediaTypeHeaderValue(BE.Common.ContentType.appjson);
using (var client = new HttpClient())
{
aPIRequestfile.FileName = filename;
aPIRequestfile.UserId = CurrentSession.Instance.VerifiedUser.UserDetailId;
aPIRequestfile.ContentType = contentType;
aPIRequestfile.IsProfile = isProfile;
client.DefaultRequestHeaders.Add("FileDetails", JsonConvert.SerializeObject(aPIRequestfile));
var ApiRequest = client.PostAsync(apiUrl, content);
if (ApiRequest != null)
{
if (ApiRequest.Result.StatusCode == HttpStatusCode.OK)
{
RepsonseMsg = ApiRequest.Result.Content.ReadAsStringAsync().Result;
}
else
RepsonseMsg = BE.ResultStatus.Failed.ToString();
}
}
Receive by API
byte[] filebytes = Request.Content.ReadAsByteArrayAsync().Result;
you will receive byte and then can save it.

download file from asp.net web api

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;
}

Download excel file using webapi and angularjs

I'm trying to download a closedXml excel file in a webapi/angularjs application.
I'm returning the data from the webapi controller on the server using:
HttpResponseMessage result = new HttpResponseMessage();
result = Request.CreateResponse(HttpStatusCode.OK);
MemoryStream stream = GetStream(workbook);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Download.xlsx"
};
return result;
and then saving it on the client using:
$scope.openExcel = function (data, status, headers, deferred) {
var type = headers('Content-Type');
var disposition = headers('Content-Disposition');
if (disposition) {
var match = disposition.match(/.*filename=\"?([^;\"]+)\"?.*/);
if (match[1])
defaultFileName = match[1];
}
defaultFileName = defaultFileName.replace(/[<>:"\/\\|?*]+/g, '_');
var blob = new Blob([data], { type: type });
saveAs(blob, defaultFileName);
Excel says the file is in a different format than specified by the extension and then doesn't open properly.
On projects I work on, I make a Controller for files(not an ApiController)
public class FilesController : Controller
{
public FileResult GetFile(/*params*/)
{
// get fileBytes
var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
return base.File(fileBytes, contentType, "Download.xlsx");
}
}
and then from angular, I open the file like this
$window.open("/Files/GetFile/" /*+ params*/);

Categories