Mvc Render Action / Partial to Response Output

Although it @Html.RenderPartialcalls a record and returns void, it is still written to StringWriter/ StringBuilder. Is there any way to render directly into ResponseStream?

Is it possible to do this with a custom IViewEngineone that implements rendering as PdfViewfor direct output to ResponseStream?

Addition

ViewResultBase.ExecuteResultshows what ViewContextis being built using Response.Output, but the debugger shows ViewContext.WriterhowStringWriter

Both of these approaches lead to StringWriter

return PartialView("view", Model)
// or
PartialView("view", Model).ExecuteResult(ControllerContext)

EDIT

It seems like System.Web.WebPages.WebPageBase ExecutePageHeirarchypushing temp StringWriterinto the context stack, so I'm not sure if this can be circumvented

SUMMARY

RenderPartial, RenderAction are not directly output to Response.Stream, none of the Razor Views will be

Decision

WebPages/Razor, StringWriter StringBuilder. , , WebFormViewEngine, .

+4
1

, :

// <summary>
// An extension methods for rendering a model/view into a stream
// </summary>
// <param name="myModel">The model you are trying render to a stream</param>
// <param name="controllerBase">This will come from your executing action</param>
// <returns></returns>
        public static Stream GetStream(CustomModel myModel, ControllerBase controllerBase)
        {
            //we will return this stream
            MemoryStream stream = new MemoryStream();

            //you can add variables to the view data
            controllerBase.ViewData["ViewDataVariable1"] = true;

            //set your model
            controllerBase.ViewData.Model = myModel;

            //The example uses the UTF-8 encoding, you should change that if you are using some other encoding.
            //write to a stream
            using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8))
            {
                using (var sw = new StringWriter())
                {
                    //render the view  ~/Views/Shared/_FeedbackMessage.cshtml (can be passed in as a parameter if you want to make it super generic)
                    var viewResult = ViewEngines.Engines.FindPartialView(controllerBase.ControllerContext, "_FeedbackMessage");

                    //create a new view context
                    var viewContext = new ViewContext(controllerBase.ControllerContext, viewResult.View, controllerBase.ViewData, controllerBase.TempData, sw);

                    //Render the viewengine and let razor do its magic
                    viewResult.View.Render(viewContext, sw);    
                    viewResult.ViewEngine.ReleaseView(controllerBase.ControllerContext, viewResult.View);

                    //get StringBuilder from StringWriter sw and write into the stream writer
                    //you could simply return the StringWriter here if that is what you were interested in doing
                    writer.Write(sw.GetStringBuilder().ToString());

                    writer.Flush();

                    stream.Position = 0;
                }

            }

            //return the stream from the above process
            return stream;
        }
0

Source: https://habr.com/ru/post/1622279/


All Articles