将响应保存为文件

时间:2016-04-27 14:52:02

标签: javascript angularjs asp.net-web-api download httpresponse

我有WebAPI方法,将HttpResponseMessage文件作为内容返回.csv

private static HttpResponseMessage FileAsAttachment(string file)
{
    var now = DateTime.Now;
    var result = new HttpResponseMessage(HttpStatusCode.OK);

    result.Content = new StringContent(file);
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); //attachment will force download
    result.Content.Headers.ContentDisposition.FileName = string.Format("Report-{0}.csv", now.ToString("MMMM"));

    return result;
}

所以我只需点击功能,即可调用服务器:

$scope.GenerateReport = function() {
     var endDate = '2016-04-30';
     UserDaysSummary.generateReport({endDate: endDate }, function (result) {
          console.log("Export");
     });
}

但我所得到的只是对内部数据的回应。 我尝试使用thisthis回答将其作为文件获取,但这不会改变任何内容。

最好,对服务器的调用具有GET方法,btw

1 个答案:

答案 0 :(得分:5)

您的GenerateReport函数是否会返回承诺?试试这个:

userDaysSummary.generateReport = function(endDate) {
    var defer = $q.defer();

    $http.get('path/to/api', { endDate: endDate }, { responseType: 'arrayBuffer' }).then(function(data, status, headers, config) {
        var results = {
            data: data, //your file is here
            headers: headers(), //headers are here
            status: status,
            config: config
        };

        //return a success promise containing the response object
        defer.resolve(results);

    }, function(data, status, headers, config) {
        defer.reject(data);
    });

    return defer.promise;
}

然后,使用承诺下载文件:

userDaysSummary.generateReport(endDate).then(function(response) {
    //get the file
    var octetStreamMime = 'application/octet-stream';

    //get the headers' content disposition
    var cd = response.headers["content-disposition"];

    //get the file name with regex
    var regex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
    var match = regex.exec(cd);

    //is there a fiel name?
    var fileName = match[1] || "myDefaultFileName.csv";

    //replace leading and trailing slashes that C# added to your file name
    fileName = fileName.replace(/\"/g, "");

    //determine the content type from the header or default to octect stream
    var contentType = response.headers["content-type"] || octetStreamMime;

    //finally, download it
    try {
        var blob = new Blob([response.data], {type: contentType});

        //downloading the file depends on the browser
        //IE handles it differently than chrome/webkit
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveOrOpenBlob(blob, fileName);
        } else {
            var objectUrl = URL.createObjectURL(blob);
            window.open(objectUrl);
        }
    } catch (exc) {
        console.log("Save Blob method failed with the following exception.");
        console.log(exc);
    }

}, function(error) {
    //an error occurred while trying the API, handle this
});