2015-05-08 29 views
4

我使用MVC 5网络API控制器,我想返回一个文件:如何从web api控制器返回文件?

[Route("")] 
public HttpResponseMessage GetFile() 
{ 
    var statusCode = HttpStatusCode.OK; 
    FileStream file = XLGeneration.XLGeneration.getXLFileExigence(); 

    return Request.CreateResponse(statusCode, file); 
} 

它不到风度的工作。

从邮递员例外情况是:

“ExceptionMessage”: “在 'ObjectContent`1' 型未能序列化反应体内容类型 '应用/ JSON;字符集= UTF-8'”

+0

查看方法的定义,第二个参数是您试图序列化的值。所以它试图做的是序列化一个'FileStream',它可能不是可序列化的。尝试将该文件读入一个字符串并将该字符串用作第二个参数。 –

+0

可能相关:http://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api – dbc

回答

2

尝试......

[Route("")] 
public HttpResponseMessage GetFile() 
{ 
    var result = new HttpResponseMessage(HttpStatusCode.OK); 
    try 
    { 
     var file = XLGeneration.XLGeneration.getXLFileExigence(); 
     result.Content = new StreamContent(file); 
     result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); 
     var value = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
     value.FileName = "Whatever your filename is"; 
     result.Content.Headers.ContentDisposition = value; 
    } 
    catch (Exception ex) 
    { 
     // log your exception details here 
     result = new HttpResponseMessage(HttpStatusCode.InternalServerError); 
    } 
    return result; 
} 

这实际上应该流回来的文件。

+0

对不起,忽略了最低的工作。 – AtefB

+0

@AtefB我已经在生产中运行了近一年的代码,唯一的区别是我正在将我的文件内容读入一个字节数组,并创建一个MemoryStream来创建StreamContent。除此之外,它是从我的生产代码中剪切和粘贴的。 – Kevin

+0

@AtefB有两种可能性,为什么这可能不适合你。如果您的XLGeneration.XLGeneration.getXLFileExigence()实际上没有返回流,或者您没有用实际文件名替换“无论您的文件名是什么”。 – Kevin

0

只是想法:

public HttpResponseMessage GetFile() 
{ 
    FileStream file = XLGeneration.XLGeneration.getXLFileExigence(); 

    using(var sr = new StreamReader(file)) 
    { 
     content = sr.ReadToEnd(); 

     return new HttpResponseMessage 
     { 
      Content = new StringContent(content, Encoding.UTF8, "application/json") 
     }; 
    } 
} 
+0

这会在发送之前将整个文件加载到内存中。 @Kevin的解决方案是可取的,因为它直接发送流到客户端。 –

+0

@Miroslav Exception @'using(var sr = new StreamReader(file))' 流不能播放 – AtefB

2

我张贴在什么情况下,任何人都为我工作作为替代别人有困难。

[ActionName("File")] 
[HttpGet] 
public HttpResponseMessage File() 
{ 
     var response = new HttpResponseMessage(HttpStatusCode.OK); 
     var stream = new System.IO.FileStream(yourFilePath, System.IO.FileMode.Open); 
     response.Content = new StreamContent(stream); 
     response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); 

     return response; 
} 
+0

这也适用于我。 – etalon11

3

我从WebAPI控制器返回byte [],并成功下载PDF。 我正在使用iTextSharp(LGPL)4.1.6免费PDF转换器。 要安装iTextSharp(LGPL/MPL),请在软件包管理器控制台中运行以下命令。

安装,包装iTextSharp的,LGPL -Version 4.1.6

服务器端代码

[Route("Export/ExportToPdf")] 

    public byte[] ExportToPdf(string html) 
    {   

     MemoryStream msOutput = new MemoryStream(); 
     TextReader reader = new StringReader(html); 
     Document document = new Document(new Rectangle(842, 595));    
     PdfWriter writer = PdfWriter.GetInstance(document, msOutput); 
     document.Open(); 
     document.HtmlStyleClass = @"<style>*{ font-size: 8pt; font-family:arial;}</style>"; 

     var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(html), null); 
     foreach (var htmlElement in parsedHtmlElements) 
     { 
      document.Add(htmlElement as IElement); 
     } 

     document.Close(); 

     return msOutput.ToArray(); 
    } 

客户端代码。

//Call this function inside of AJAX success. 
function ExportToPDF(data) { 

    //base64 To ArrayBuffer 
    var binaryString = window.atob(data); 
    var binaryLen = binaryString.length; 
    var bytes = new Uint8Array(binaryLen); 
    for (var i = 0; i < binaryLen; i++) { 
     var ascii = binaryString.charCodeAt(i); 
     bytes[i] = ascii; 
    } 
    //------- 

    var link = document.createElement('a'); 
    link.href = window.URL.createObjectURL(new Blob([bytes], { type: 'application/pdf' })); 
    link.download = "Report.pdf"; 
    link.click(); 
}