I have to create a large XML Spreadsheet and it now seems to have hit the threshold on what it can cope with in one go.
I'm not sure on how to split it out so wanted to know if there is a way to increase the memory allocation for internal purposes?
Code that is causing the error is below:
private string RenderViewToString()
{
using (var writer = new StringWriter())
{
var view = ViewEngines.Engines.FindView(_context, _viewName, null).View as RazorView;
var viewDataDictionary = new ViewDataDictionary<TModel>(_model);
var viewCtx = new ViewContext(_context, view, viewDataDictionary, new TempDataDictionary(), writer);
viewCtx.View.Render(viewCtx, writer);
return writer.ToString();
}
}
It falls on the Render()
when a user decides to download ALL data from the possible combinations of data, before the enrichment of data this file would be circa 55mb converted into an Excel document. Now that the columns have been doubled, the line of code rendering the writer is falling over.
viewCtx.View.Render(viewCtx, writer);
Has anyone got a workaround or know a way to split the relevant data into manageable chunks without recoding it all?
It obtains the data from a view model and that itself takes from 1 to tens of thousands of rows across multiple tables and all is needed by the users in a singular Excel download which is causing issues.
The string is going out to this code:
protected override void WriteFile(HttpResponseBase response)
{
response.Write(RenderViewToString());
}
But the whole issue of the of whether it needs to be returned string is irrelevant as it never gets that far due to the ViewContext.View.Render(ViewContext, TextWriter) falling over, so is there a way to render the ViewContext to something without it falling over due to a relatively small file (60+ MB) causing it issues?
I have tried to allow the large file use in web.config (A colleague suggested it) but that didnt work.
At the moment the ViewContext is too large to render so I just need to find a way to render it without using the in built one, any ideas?
----- Edit -----
Big thanks to Joe, I modified your code as I dont have IIS Set up to use the HttpContext headers, but the following code did the trick:
HttpContext.Current.Response.Clear();
using (var writer = new StreamWriter(HttpContext.Current.Response.OutputStream))
{
var view = ViewEngines.Engines.FindView(_context, _viewName, null).View
as RazorView;
var viewDataDictionary = new ViewDataDictionary<TModel>(_model);
var viewCtx = new ViewContext(_context,
view, viewDataDictionary, new TempDataDictionary(), writer);
viewCtx.View.Render(viewCtx, writer);
}
return null;
Now produces a 70MB file no problems.