Saturday, November 7, 2020

 How to send Large Size Object in ASP.Net Web API

There are multiples issue when you send the large object or file to the web API that hosted within IIS context, because there are some default limitation on the service by the Framework.

you might be faced an out of memory issues when allowing the Large Object especially large bytes

You can configure the large size by through IIS configuration or by ASP.Net 

1. ASP.NET

ASP.NET runtime has its own file size limit which is located under the httpRuntime element of the web.config.

The default size is set to 4096 KB (4 MB). it’s set in KB instead of bytes as example below:


2. IIS

The default file is 30000000 bytes more then 28 MB, if you tried to send file with more then 28 mb the response will be 404 error, So you need to explicitly change the web.config file to allow the large size. you can use maxRequestLength and or maxAllowedContentLength depend on the IIS version you are using.

maxRequestLength option to set the the maximum request size for ASP.NET, whereas maxAllowedContentLength use to set the maximum length of content in a request supported by IIS

See the example Below:


By default, Web API buffer the request input stream in to the memory and it can cause out of memory error since we have increased the limit of 2 GB with just couple of simultaneous uploads. there is a way to to change this mode for the Web API so that its streamed mode deal with uploaded file and not buffer the entire request stream in memory.
We just need to replace the default IHostBufferPolicySelector  with our custom implementation as below:
public interface IHostBufferPolicySelector
{
   bool UseBufferedInputStream(object hostContext);
   bool UseBufferedOutputStream(HttpResponseMessage response);
}

 per request service will makes a decision that request should be buffered or not

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);
   }
}

Now we need to register the service in GlobalConfiguration as this service should always be global.

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

In .Net Framework V 4 by default HttpClient will buffer the body. so if you want to control the request/ response whether they are buffered or streamed to overcome the out of memory issue, you should use the HttpWebRequest directly as we have more control on HttpWebRequest over HttpClient even it lies under the HttpClient but these properties are not exposed to the consumer by HttpClient

HttpWebRequest.AllowReadStreamBuffering 
HttpWebRequest.AllowWriteStreamBuffering

In .NET 4.5 and greater version. HttpClient does not buffer the response by default.

No comments:

Post a Comment

Search This Blog