尝试使用angularJS和c#webapi从服务器下载文件

将文件上传到服务器时,它很棒; 没有损坏的文件。 然而,当我下载文件时(除了纯粹的txt:s,它们是woork),它们的大小会变大并变得腐败。 经过大量的调查,我不知道会出现什么问题。 我只是将文件作为流写入响应并下载blob。
欢迎任何想法!

严重依赖此Thread解决方案; 使用AngularJS从ASP.NET Web API方法下载文件

现行守则如下;

的WebAPI:

[Route("GetFile")] public HttpResponseMessage GetFile() { HttpResponseMessage result = null; //Get file object here try { IEnumerable 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); } } 

视图:

  

控制器:

  /******** 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; }); } 

添加了arraybuffer作为GET请求的响应类型,现在浏览器正确解释文件。

  /******** 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 }