Maybe you should consider using gRPC service and data chunking.
ASP.NET Framework Returning Large Response
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.
2 answers
Sort by: Most helpful
-
-
Yijing Sun-MSFT 7,086 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