ASP.NET Framework Returning Large Response

Zaid Abu-Hijleh 1 Reputation point
2021-01-08T20:03:10.81+00:00

I have an ASP.NET framework web application that processes documents and returns it in a template contract. It works fine for most file, but if the processed file is large, the response is too large to return. This is what we are returning:

public class ControllerBase : ApiController
 {
           .
           .
           .
           .
           protected IHttpActionResult CheckForReport(string guid, 
RepositoryStatus.REQUEST_TYPE requestType, bool returnReport)
 {
                  .
                  .
                  .
                   switch (reportStatus.RequestType)
                   {
                           case RepositoryStatus.REQUEST_TYPE.TagTree:
                               return Ok(Repository.GetTagTree(guid));
                           case RepositoryStatus.REQUEST_TYPE.Metrics:
                               return Ok(Repository.GetMetrics(guid));
                           case RepositoryStatus.REQUEST_TYPE.DocGen:
                                return Ok(Repository.GetReport(guid));
                       }
                 }
     }

Where Repository.GetReport(guid) returns a Document Interface object:

    /// <summary>
 /// The generated document we are sending back to the client.
 /// </summary>
 [DataContract]
 public class Document

Im trying to return the document as a stream, but am struggling to find the appropriate return type for the ApiController class. Any suggestions?

I did this in .NET core, and this is essentially what I ultimately want to be able to do, or some for of this in .net framework

[HttpGet]
        public IActionResult Get()
        {
            string filename = "C:\\WindwardRESTClientSamples\\Windward-RESTful-V2-.NET-Core-Client-Sample\\files\\1gb.docx";
            byte[] bytes = System.IO.File.ReadAllBytes(filename);
            //var dataStream = new MemoryStream(bytes);
            //var temp = new FileResult(dataStream, filename);
            string contentType;
            new FileExtensionContentTypeProvider().TryGetContentType(filename, out contentType);
            contentType = contentType ?? "application/octet-stream";
            return File(bytes, contentType);

UPDATE: NEW CODE ADDED:

 public class FileResult : IHttpActionResult
    {

        private readonly Document genDocument;
        private readonly string contentType;

        public FileResult(Document doc, string contentType = null)
        {
            this.genDocument = doc;
            this.contentType = contentType;
        }

        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            return Task.Run(() =>
            {
                var memStream = new MemoryStream(genDocument.Data);
                var response = new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new StreamContent(memStream)
                };

                //var contentType = this.contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath));
                var tempType = this.contentType ?? "applicatiton/pdf";
                response.Content.Headers.ContentType = new MediaTypeHeaderValue(tempType);

                return response;
            }, cancellationToken);
        }
    }

Then I would return a FileResult object in my controller class:

case RepositoryStatus.REQUEST_TYPE.DocGen:
                        return new FileResult(Repository.GetReport(guid));

I also added these to the web.config file:
< maxRequestLength="2097152" executionTimeout="180"/>

These changes helped slightly, but I still get a out of memory exception thrown.

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,454 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,844 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Duane Arnold 3,221 Reputation points
    2021-01-10T15:30:49.79+00:00

    Maybe you should consider using gRPC service and data chunking.

    https://ops.tips/blog/sending-files-via-grpc/


  2. Yijing Sun-MSFT 7,076 Reputation points
    2021-01-11T06:45:14.39+00:00

    Hi @Zaid Abu-Hijleh ,

    As far as I think, if you have files that large, never use byte[] or MemoryStream in your code. Only operate on streams.You could return StreamContent in ApiController class.
    Could you tell us how many bytes of your file?If the file is too large,you could change the setting.
    More details,you could refer to below article:
    file-uploads


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Yijing Sun


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.