尝试使用服务器angularJS和C#的WebAPI下载文件

尝试使用服务器angularJS和C#的WebAPI下载文件

本文介绍了尝试使用服务器angularJS和C#的WebAPI下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将文件上传到服务器时,它进入大;没有任何损坏的文件。然而,当我下载文件(不是纯粹的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.webkitUR​​L || 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下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-20 17:20