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

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

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

我确信这个过程有一个名字,但我不知道它——这使得寻找它变得相当困难.

在Web API中,我做了很多关于响应流的工作,但是我以前从来没有考虑过请求流.

据我所知,我最需要做的就是想办法:

  • 在流完成上载之前开始处理流.
  • 使用HttpClient流式传输相同的请求,以将相同的数据流式传输到另一个HTTP端点.

谁能给我一些建议吗?

推荐答案

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

需要考虑的几件事:

默认情况下,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;

在-http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/之前,我已经在博客中详细介绍了如何在WebAPI中处理大型文件,希望你会发现这很有用.

2)其次,如果您使用HttpClient,那么在.NET4中,默认情况下它会缓冲请求正文,所以您应该真正使用.NET4.5.

如果你必须使用.NET 4您必须直接与HttWebRequest合作:

3).尽可能地将数据推送到客户端,如果你想这样做的话,这是绝对可能的,PushStreamContent.

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

Asp.net相关问答推荐

禁用托管优化并重新启动调试实际上在 Visual Studio 中更改了哪些设置?

为什么 @Html.EditorFor 和 @Html.PasswordFor 在 MVC 中创建不同的样式框?

我可以将图像添加到 ASP.NET 按钮吗?

静态字段与会话变量

更改 GridView 中列的标题文本

是否可以访问位于另一个项目中的 MVC 视图?

ASP.NET - AppDomain.CurrentDomain.GetAssemblies() - AppDomain 重新启动后缺少程序集

将命令行参数传递给 ASP.NET Core 中的 Startup 类

ASP.NET MVC4 jquery/javascript 包的使用

正在检索组件的 COM 类工厂......错误:80070005 访问被拒绝. (来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))

'Microsoft.ACE.OLEDB.12.0' 提供程序未在本地计算机上注册.

ASP.NET Core 中的授权. [Authorize] 属性总是 401 Unauthorized

无法使用单例Microsoft.AspNetCore.Hosting.Internal.HostedServiceExecutor中的范围服务MyDbContext

如何设置 CSS 切换器

LINQ to Entities 无法识别 MVC 4 中的System.String ToString()方法

如何从 SQL Server 2008 本身获取客户端 IP 地址?

在 ASP.NET 4.5 WebForms 中通过 bundle.config 与 BundleConfig.cs Bundle 资源

实体框架:如何解决外键约束可能导致循环或多个级联路径?

ASP.NET MVC 路由的无限 URL 参数

GridView 按代码隐藏列