Khi tải tệp lên máy chủ, nó sẽ trở nên tuyệt vời; không có tệp bị hỏng. Tuy nhiên khi tôi tải xuống các tệp (khác với txt thuần túy: chúng sẽ woork) chúng phát triển về kích thước và trở nên bị hỏng. Sau nhiều lần điều tra, tôi không biết điều gì có thể sai. Im chỉ cần viết tệp làm luồng cho phản hồi và tải xuống blob.
Bất kỳ ý tưởng nào đều được hoan nghênh!Cố gắng tải xuống tệp từ máy chủ bằng angularJS và C# webapi
Dựa chủ yếu vào Chủ đề này cho giải pháp; Download file from an ASP.NET Web API method using AngularJS
Mã hiện tại bên dưới;
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);
}
}
Xem:
<button type="button" class="btn btn-default btn-sm" data-localize="DOWNLOAD" ng-click="downloadFiles(file)">
Download file
</button>
Bộ điều khiển:
/******** 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;
});
}
Cảm ơn câu trả lời, tôi đã thử vài ngày và không thể tìm thấy lý do tệp tải xuống của tôi bị hỏng và có nhiều byte hơn so với tải lên ban đầu. Tôi đã triển khai giải pháp giống như của bạn ngoại trừ responseType: 'arraybuffer'. Nhưng không thể nghĩ đây có thể là vấn đề lớn. – Aamol