上载请求正文之前发送响应

上载请求正文之前发送响应

本文介绍了ASP.Net Web API:在读取/上载请求正文之前发送响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对控制器有一个操作,应该将较大的文件(500mb-2gb)上传到该控制器上.例如,

I have an action on my controller to which large (500mb - 2gb) files are supposed to be uploaded. Eg,

[HttpPost]
public void PostFile([FromUri]Guid uploadId)
{
  ...
}

在正文中执行了几项检查(例如,uploadId是否存在),然后将HTTP请求发布的正文写入磁盘(/网络共享).

Inside the body, a couple of checks are performed (such as if the uploadId exists), and then the HTTP Request's posted body is written to disk (/network share).

我以为我已经钉上了这个钉子,因为如果没有创建uploadId,我几乎可以立即拒绝HTTP请求,方法是抛出HttpResponseException,但我发现即使在这种情况下,Request的主体也可以完全上载到服务器并保存到磁盘的ASP.Net临时文件文件夹.这意味着客户端必须完全上载一个文件(大约需要5-10分钟),才能发现该文件已被服务器拒绝.

I thought I had this nailed, in that I could reject the HTTP request almost immediately if the uploadId hadn't been created, by throwing a HttpResponseException, but I've just discovered that even in this case, the Request's body gets fully uploaded to the server and saved to disk the ASP.Net Temporary Files folder. This means that the client has to fully upload a file (taking approximately 5-10 minutes) just to find out that it has been rejected by the server.

如何避免这种情况?有什么方法可以防止IIS将主体写入磁盘并允许控制器处理流吗?我感到很沮丧的是,客户端开始上传与请求到达我自己的代码之间有5分钟的延迟,因为ASP.Net必须做自己的事情并将上传写入本地磁盘.

How do I avoid this? Is there any way to prevent IIS from writing the body to disk, and allowing the controller to handle the stream? I find it frustrating that there is a 5 minute delay between the client starting the upload, and the request hitting my own code, because ASP.Net has to do its own thing and write the upload to local disk.

编辑

有人问我如何读取上传数据.本质上,使用此方法:

I've been asked how I'm reading the upload data. Essentially, using this method:

        /// <summary>
        /// Saves the current request's upload stream to the proivded path.
        /// </summary>
        /// <param name="destinationPath">The path to save to.</param>
        /// <returns></returns>
        private async Task<FileInfo> SaveUploadToDiskAsync(string destinationPath)
        {
            using (var httpContent = Request.Content)
            {
                using (FileStream fileStream = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
                {
                    await httpContent.CopyToAsync(fileStream);

                    return new FileInfo(destinationPath);
                }
            }
        }

推荐答案

您可以通过实现自定义WebHostBufferPolicySelector

You can configure Web API to work in bufferless mode (streaming) for a specific controller (or globally, for that matter) by implementing a custom WebHostBufferPolicySelector

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(), "upload", StringComparison.InvariantCultureIgnoreCase))
            return false;
      }

      return true;
   }

   public override bool UseBufferedOutputStream(HttpResponseMessage response)
   {
      return base.UseBufferedOutputStream(response);
   }
}

我为在Web API中处理大文件

这篇关于ASP.Net Web API:在读取/上载请求正文之前发送响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-22 22:48