Overriding WebHostBufferPolicySelector for Non-Buffered File Upload

后端 未结 1 1696
臣服心动
臣服心动 2021-02-06 14:20

In an attempt to create a non-buffered file upload I have extended System.Web.Http.WebHost.WebHostBufferPolicySelector, overriding function UseBufferedInputStream() as described

相关标签:
1条回答
  • 2021-02-06 14:57

    WebHostBufferPolicySelector only specifies if the underlying request is bufferless. This is what Web API will do under the hood:

    IHostBufferPolicySelector policySelector = _bufferPolicySelector.Value;
    bool isInputBuffered = policySelector == null ? true : policySelector.UseBufferedInputStream(httpContextBase);
        Stream inputStream = isInputBuffered
                      ? requestBase.InputStream
              : httpContextBase.ApplicationInstance.Request.GetBufferlessInputStream();
    

    So if your implementation returns false, then the request is bufferless.

    However, ReadAsMultipartAsync() loads everything into MemoryStream - because if you don't specify a provider, it defaults to MultipartMemoryStreamProvider.

    To get the files to save automatically to disk as every part is processed use MultipartFormDataStreamProvider (if you deal with files and form data) or MultipartFileStreamProvider (if you deal with just files).

    There is an example on asp.net or here. In these examples everything happens in controllers, but there is no reason why you wouldn't use it in i.e. a formatter.

    Another option, if you really want to play with streams is to implement a custom class inheritng from MultipartStreamProvider that would fire whatever processing you want as soon as it grabs part of the stream. The usage would be similar to the aforementioned providers - you'd need to pass it to the ReadAsMultipartAsync(provider) method.

    Finally - if you are feeling suicidal - since the underlying request stream is bufferless theoretically you could use something like this in your controller or formatter:

                Stream stream = HttpContext.Current.Request.GetBufferlessInputStream();
                byte[] b = new byte[32*1024];
                while ((n = stream.Read(b, 0, b.Length)) > 0)
                {
                    //do stuff with stream bit
                }
    

    But of course that's very, for the lack of better word, "ghetto."

    0 讨论(0)
提交回复
热议问题