问题描述
在将文件上传到服务器时,它进入大;没有任何损坏的文件。然而,当我下载文件(不是纯粹的TXT等:就是他们woork)它们生长在大小和损坏。调查了很多之后,我不知道什么可能是错误的。林只是写文件作为流到响应和下载斑点。
任何想法,欢迎!
主要依赖于这个主题的解决方案; Download从使用的ASP.NET Web API方法文件angularjs
目前的code以下;
的WebAPI:
[路线(的GetFile)
公众的Htt presponseMessage的GetFile()
{
HTT presponseMessage结果= NULL;
//获取文件对象这里
尝试
{
IEnumerable的<字符串> headerValues = Request.Headers.GetValues(FILEID);
INT键= Int32.Parse(headerValues.FirstOrDefault());
VAR fetchFile = db.FileRecords.Single(A => a.id ==键);
VAR localFilePath = fetchFile.path + fetchFile.name;
如果(!System.IO.File.Exists(localFilePath))
{
结果= Request.CreateResponse(的HTTPStatus code.Gone);
}
其他
{//服务文件到客户机
//我已经使用的X-名头发送的文件名。这是为了方便自定义标题。
//你应该设置内容类型MIME头为你的回应了,所以浏览器知道的数据格式。
VAR信息= System.IO.File.GetAttributes(localFilePath);
结果= Request.CreateResponse(的HTTPStatus code.OK);
result.Content =新StreamContent(新的FileStream(localFilePath,FileMode.Open,FileAccess.Read));
result.Content.Headers.ContentType =新MediaTypeHeaderValue(应用程序/八位字节流);
result.Content.Headers.Add(X-文件名,fetchFile.name);
result.Content.Headers.ContentDisposition =新System.Net.Http.Headers.ContentDispositionHeaderValue(附件);
result.Content.Headers.ContentDisposition.FileName = fetchFile.name;
}
返回结果;
}
赶上(例外五)
{
返回Request.CreateResponse(的HTTPStatus code.BadRequest);
}
}
查看:
<按钮式=按钮级=BTN BTN默认BTN-SM数据本地化=下载NG点击=downloadFiles(文件)>
下载文件
< /按钮>
控制器:
/ ********文件下载********** /
$ scope.downloadFiles =功能(文件){
$ HTTP({
方法:GET,
缓存:假的,
网址:主机+API /文件/的GetFile,
标题:{
内容类型:应用/ JSON的;字符集= UTF-8,
FILEID:file.id
}
}),成功(功能(数据,状态,标题){
VAR octetStreamMime ='应用程序/八位字节流;
VAR成功= FALSE;
//获取头
标题=标题();
//获取文件名从X文件名头或默认为download.bin
VAR文件名=标题[X-文件名] || download.bin;
//确定从页眉或默认为应用程序/八位字节流的内容类型
VAR的contentType =标题['内涵式'] || octetStreamMime;
尝试 {
执行console.log(文件名);
//尝试使用msSaveBlob如果支持的话
的console.log(尝试saveBlob方法......);
VAR BLOB =新的Blob([数据] {类型:contentType中});
如果(navigator.msSaveBlob)
navigator.msSaveBlob(BLOB,文件名);
其他 {
//尝试使用其他saveBlob实现,如果有的话
VAR saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
如果(saveBlob ===未定义)抛出不支持;
saveBlob(BLOB,文件名);
}
的console.log(saveBlob成功);
成功= TRUE;
}赶上(前){
的console.log(saveBlob方法失败,出现以下异常:);
执行console.log(前);
}
如果(!成功){
//获取blob的URL创建者
VAR urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
如果(urlCreator){
//尽量使用下载链接
VAR链接= document.createElement方法('A');
如果(在链接'下载'){
//尝试模拟点击
尝试 {
// prepare一个blob网址
的console.log(试图与模拟点击下载链接的方法......);
VAR BLOB =新的Blob([数据] {类型:contentType中});
VAR URL = urlCreator.createObjectURL(BLOB);
link.setAttribute(HREF,网址);
//设置下载属性(支持在Chrome 14+ /火狐20+)
link.setAttribute(下载,文件名);
//模拟点击下载链接
VAR事件= document.createEvent('MouseEvents');
event.initMouseEvent('点击',真的,真的,窗口,1,0,0,0,0,假的,假的,假的,假的,0,NULL);
link.dispatchEvent(事件);
的console.log(与模拟点击下载链接方法成功);
成功= TRUE;
}赶上(前){
的console.log(与模拟点击下载链接的方法失败,出现以下异常:);
执行console.log(前);
}
}
如果(!成功){
//回退到window.location的方法
尝试 {
// prepare一个blob网址
使用window.location的时强制下载//使用应用程序/八位字节流
的console.log(用了window.location尝试下载链接的方法......);
VAR BLOB =新的Blob([数据] {类型:octetStreamMime});
VAR URL = urlCreator.createObjectURL(BLOB);
了window.location = URL;
的console.log(与window.location的下载链接方法成功);
成功= TRUE;
}赶上(前){
的console.log(与window.location的下载链接的方法失败,出现以下异常:);
执行console.log(前);
}
}
}
}
如果(!成功){
//回退到window.open方法
的console.log(无工作的方法用于保存arraybuffer,用最后一招的window.open);
的window.open(httpPath,'_blank','');
}
/ ****************** /
})错误(功能(数据,状态){
的console.log(请求失败,状态:+状态);
//选择写错误出范围
//$scope.errorDetails =请求失败,状态:+状态;
});
}
补充arraybuffer作为GET请求的responsetype,现在的浏览器中正确interprits文件。
/ ********文件下载********** /
$ scope.downloadFiles =功能(文件){
$ HTTP({
方法:GET,
缓存:假的,
网址:主机+API /文件/的GetFile,
responseType:arraybuffer,
标题:{
内容类型:应用/ JSON的;字符集= UTF-8,
FILEID:file.id
}
When uploading files to the server it goes great; no damaged files. However when i download files ( other than pure txt:s they woork)they grow in size and become corrupt. After alot of investigation I dont know what could be wrong. Im simply writing the fileas a stream to the response and downloading the blob.
Any ideas are welcome!
Relied heavily on this Thread for the solution ; Download file from a ASP.NET Web API method using angularjs
Current Code below;
WebApi:
[Route("GetFile")]
public HttpResponseMessage GetFile()
{
HttpResponseMessage result = null;
//Get file object here
try
{
IEnumerable<string> headerValues = Request.Headers.GetValues("fileID");
int key = Int32.Parse(headerValues.FirstOrDefault());
var fetchFile = db.FileRecords.Single(a => a.id == key);
var localFilePath = fetchFile.path + fetchFile.name;
if (!System.IO.File.Exists(localFilePath))
{
result = Request.CreateResponse(HttpStatusCode.Gone);
}
else
{// serve the file to the client
//I have used the x-filename header to send the filename. This is a custom header for convenience.
//You should set the content-type mime header for your response too, so the browser knows the data format.
var info = System.IO.File.GetAttributes(localFilePath);
result = Request.CreateResponse(HttpStatusCode.OK);
result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.Add("x-filename", fetchFile.name);
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = fetchFile.name;
}
return result;
}
catch (Exception e)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
View:
<button type="button" class="btn btn-default btn-sm" data-localize="DOWNLOAD" ng-click="downloadFiles(file)">
Download file
</button>
Controller:
/******** FILE DOWNLOAD **********/
$scope.downloadFiles = function (file) {
$http({
method: 'GET',
cache: false,
url: host + 'api/Files/GetFile',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'fileID': file.id
}
}).success(function (data, status, headers) {
var octetStreamMime = 'application/octet-stream';
var success = false;
// Get the headers
headers = headers();
// Get the filename from the x-filename header or default to "download.bin"
var filename = headers['x-filename'] || 'download.bin';
// Determine the content type from the header or default to "application/octet-stream"
var contentType = headers['content-type'] || octetStreamMime;
try {
console.log(filename);
// Try using msSaveBlob if supported
console.log("Trying saveBlob method ...");
var blob = new Blob([data], { type: contentType });
if (navigator.msSaveBlob)
navigator.msSaveBlob(blob, filename);
else {
// Try using other saveBlob implementations, if available
var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
if (saveBlob === undefined) throw "Not supported";
saveBlob(blob, filename);
}
console.log("saveBlob succeeded");
success = true;
} catch (ex) {
console.log("saveBlob method failed with the following exception:");
console.log(ex);
}
if (!success) {
// Get the blob url creator
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
if (urlCreator) {
// Try to use a download link
var link = document.createElement('a');
if ('download' in link) {
// Try to simulate a click
try {
// Prepare a blob URL
console.log("Trying download link method with simulated click ...");
var blob = new Blob([data], { type: contentType });
var url = urlCreator.createObjectURL(blob);
link.setAttribute('href', url);
// Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
link.setAttribute("download", filename);
// Simulate clicking the download link
var event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
link.dispatchEvent(event);
console.log("Download link method with simulated click succeeded");
success = true;
} catch (ex) {
console.log("Download link method with simulated click failed with the following exception:");
console.log(ex);
}
}
if (!success) {
// Fallback to window.location method
try {
// Prepare a blob URL
// Use application/octet-stream when using window.location to force download
console.log("Trying download link method with window.location ...");
var blob = new Blob([data], { type: octetStreamMime });
var url = urlCreator.createObjectURL(blob);
window.location = url;
console.log("Download link method with window.location succeeded");
success = true;
} catch (ex) {
console.log("Download link method with window.location failed with the following exception:");
console.log(ex);
}
}
}
}
if (!success) {
// Fallback to window.open method
console.log("No methods worked for saving the arraybuffer, using last resort window.open");
window.open(httpPath, '_blank', '');
}
/******************/
}).error(function (data, status) {
console.log("Request failed with status: " + status);
// Optionally write the error out to scope
//$scope.errorDetails = "Request failed with status: " + status;
});
}
Added arraybuffer as a responsetype of the GET request, now the browser interprits the files correctly.
/******** FILE DOWNLOAD **********/
$scope.downloadFiles = function (file) {
$http({
method: 'GET',
cache: false,
url: host + 'api/Files/GetFile',
responseType:'arraybuffer',
headers: {
'Content-Type': 'application/json; charset=utf-8',
'fileID': file.id
}
这篇关于尝试使用服务器angularJS和C#的WebAPI下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!