【问题标题】:WebApi file download via handler通过处理程序下载 WebApi 文件
【发布时间】:2015-12-30 15:32:17
【问题描述】:

我正在使用 WebAPI 下载 .pdf 文件,如下所示:

[HttpGet]
public async Task<HttpResponseMessage> DownloadFile(string id, bool attachment = true)
{
HttpResponseMessage result = null;

try
{
    MyService service = new MyService();
    var bytes = await service.DownloadFileAsync(id);

    if (bytes != null)
    {
        result = GetBinaryFile(personalDocument, string.Format("{0}.pdf", id), attachment);
    }
    else
    {
        result = new HttpResponseMessage(HttpStatusCode.NotFound);
    }
}
catch (Exception ex)
{
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest) { ReasonPhrase = "ServerError" });
}

return result;
}
private HttpResponseMessage GetBinaryFile(byte[] bytes, string fileName, bool attachment)
{
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
   // result.Content = new ByteArrayContent(bytes);
result.Content = new StreamContent(new System.IO.MemoryStream(bytes));
//result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("inline");

if (attachment)
{
    result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
}

result.Content.Headers.ContentDisposition.FileName = fileName;
result.Content.Headers.ContentLength = bytes.Length;
return result;
}

现在,我看到它冻结了我的网站,所以我想更改它,并通过处理程序下载一个 pdf 文件,是否可以通过客户端的任何更改路由到 IHttpHandler?按 Route 属性?

【问题讨论】:

  • 也可以使 GetBinaryFile() 方法异步
  • GetBinaryFile 只是用 HttpResponseMessage 包装文件并返回结果。
  • getbinaryfile 会冻结您的网站。你需要能够调用等待
  • 我把它作为异步方法,问题仍然存在..
  • 它是否挂在所有浏览器上?当我意识到 PDF 在除 IE11 之外的所有其他浏览器上都可以正常下载时,我目前正试图找出一个类似的问题

标签: c# asp.net-web-api asp.net-web-api2


【解决方案1】:

http://www.fsmpi.uni-bayreuth.de/~dun3/archives/task-based-ihttpasynchandler/532.html 的文章帮助我实现了异步处理程序。

通过 web.config 可以路由到地点:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true"></modules>
  <handlers>  
    <add
       name="DownFile"
       path="/api/downloads/MyDownload.axd"
       type="MyProject.WebApi.Handlers.MyDownloadAsyncHandler, MyProject.WebApi"
       verb="GET"/>
  </handlers>
</system.webServer>

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您会尝试将一些内容从服务器发送给用户。如果是这样,请尝试使用PushStreamContent 类型,实际上您不需要为此设置特定的处理程序。

    PushStreamContent 发送 zip 文件的示例

    ZipFile zip = new ZipFile()
    
    // Do something with 'zip'
    
    var pushStreamContent = new PushStreamContent((stream, content, context) =>
    {
        zip.Save(stream);
        stream.Close();
    }, "application/zip");
    
    HttpResponseMessage response = new HttpResponseMessage
    {
        Content = pushStreamContent,
        StatusCode = HttpStatusCode.OK
    };
    
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        FileName = "fileName"
    };
    
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");
    
    return response;
    

    【讨论】:

    • 我不能,因为我已经做过一些类似的事情,但总是第一次冻结我的网站,所以我使用处理程序。
    • 实际上,我不应该冻结您的网站。也许您有一些运行速度太慢的处理程序或逻辑?另外,如果您不使用异步控制器方法,请尝试使用 - 它还应该删除所有冻结状态
    • 我使用 web api 和 angular 站点,正如你所看到的,所有的方法都是异步的:) 但似乎如果我下载一个文件并将附件设置为 true,它就会冻结,所以我与处理程序一起工作,问题为我解决了:)
    • 抱歉,错过了异步 :)。好的,如果它解决了你的问题)
    猜你喜欢
    • 2015-02-06
    • 2018-05-05
    • 1970-01-01
    • 2020-12-02
    • 2015-07-07
    • 2014-01-01
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    相关资源
    最近更新 更多