I'm developing net6.0 MVC app. I use partial view rendering to the string format in my app. I make Ajax request to the app and expect it to form a Json containing rendered partial view as a prop. There is a method I use to render partial to a string below
public static string RenderPartialViewToString(Controller controller, string partialPath, object model)
{
if (string.IsNullOrEmpty(partialPath))
{
//Set Action name as partial name
partialPath = controller.GetActionNameFromRouteData();
}
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
// Find partial view file
var viewEngine = DependencyResolverHelper.GetService<ICompositeViewEngine>();
var viewResult = viewEngine.FindView(controller.ControllerContext, partialPath, false);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw, new HtmlHelperOptions());
viewResult.View.RenderAsync(viewContext).GetAwaiter().GetResult();
return sw.GetStringBuilder().ToString();
}
}
The problem is once I call viewResult.View.RenderAsync(viewContext).GetAwaiter().GetResult() it seems it captures and blocks Response.Body of current HttpContext so I can't form and return expected json anymore.
There is custom json result class I use to form the response
The exception
System.ObjectDisposedException: Cannot access a closed Stream.
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.MemoryStream.WriteAsync(ReadOnlyMemory`1 buffer, CancellationToken cancellationToken)
--- End of stack trace from previous location ---
at System.IO.Pipelines.StreamPipeWriter.FlushAsyncInternal(Boolean writeToStream, ReadOnlyMemory`1 data, CancellationToken cancellationToken)
at Web.Controllers.BaseCustomController`1.JsonNetResult.ExecuteResultAsync(ActionContext context)
Could anyone assist?

This problem can be solved by creating fake http context:
new FeatureCollection(...)is important. If you look at source ofDefaultHttpResponse, when changing response's body,IHttpResponseBodyFeaturefeature is replaced in http context. That's whynew FeatureCollection(...)is used here, because it creates a snapshot of original http context's features, so originalIHttpResponseBodyFeaturefeature won't be replaced, e.g. original response body won't be changed.