WebAPI请求流支持

本文关键字:支持 请求 WebAPI | 更新日期: 2023-09-27 17:54:55

我正在写一个ASP。. NET Web API应用程序,要求我接受文件上传并将该文件转发到另一个HTTP端点。

我担心,如果许多用户试图上传一个100MB的文件(这是一个有效的用例),那么我的应用程序将有一个大的内存占用,并且根据大请求的数量,这个占用可能会变得很大,我的应用程序将会崩溃和死亡。

理想情况下,当web服务器开始接收文件时,我想开始将文件流式传输到另一个HTTP端点,以显着减少服务器上的负载。

我确定这个过程有一个名称,但我不知道它-这使得搜索它相当困难。

我已经在Web API中做了相当多的响应流工作,但我以前从未考虑过请求流。

我只能说我需要弄清楚如何:

  • 在上传完成之前开始处理流。
  • 使用HttpClient将相同的请求流式传输到另一个HTTP端点。
谁能给我一些建议?

WebAPI请求流支持

这是个有趣的问题。我将尽力给出一些一般性的建议。

有几点需要考虑:

1) Web API默认缓冲请求,因此您担心内存占用可能相当大是完全合理的。你可以强制Web API以流模式处理请求:

    public class NoBufferPolicySelector : WebHostBufferPolicySelector
    {
       public override bool UseBufferedInputStream(object hostContext)
       {
          var context = hostContext as HttpContextBase;
          if (context != null)
          {
             if (string.Equals(context.Request.RequestContext.RouteData.Values["controller"].ToString(), "uploading", StringComparison.InvariantCultureIgnoreCase))
                return false;
          }
          return true;
       }
       public override bool UseBufferedOutputStream(HttpResponseMessage response)
       {
          return base.UseBufferedOutputStream(response);
       }
    }

然后替换服务:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new NoBufferPolicySelector());

请注意,由于WebHost和SelfHost之间的差异,这种更改只能在WebHost中进行。如果端点是selfHosted,则必须在GlobalConfig级别设置流模式:

//requests only
selfHostConf.TransferMode = TransferMode.StreamedRequest;
//responses only
selfHostConf.TransferMode = TransferMode.StreamedResponse;
//both
selfHostConf.TransferMode = TransferMode.Streamed;

我以前写过关于在Web API中处理大文件的更详细的博客- http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/,希望你会发现它很有用。

2)其次,如果你使用HttpClient,在。net 4中它默认缓冲请求体,所以你应该真正使用。net 4.5。

如果你必须使用。net 4,你必须直接使用HttWebRequest:——http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowreadstreambuffering.aspx——http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowwritestreambuffering.aspx

3)至于将数据推送到客户端,这绝对是可能的,如果你想这样做,与PushStreamContent。Henrik在这里有一个简短的介绍性帖子- http://blogs.msdn.com/b/henrikn/archive/2012/04/23/using-cookies-with-asp-net-web-api.aspx(它基于Web API RC位,所以你可能需要调整一些签名等)。我还在这里写了关于推送流数据块的博客- http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/

EDIT:要查看请求中PushStreamContent的示例,您可以查看此示例解决方案- http://aspnet.codeplex.com/SourceControl/changeset/view/bb167f0b0013#Samples/Net45/CS/WebApi/UploadXDocumentSample/ReadMe.txt