2015-12-30 3 views
4

Хотя @Html.RenderPartial звонки записывают и возвращают void, он все еще записывает StringWriter/StringBuilder. Есть ли способ сделать прямо на ResponseStream?Mvc Render Action/Partial to Response Output

Это можно сделать с помощью пользовательского IViewEngine, который реализует рендер как PdfView для прямого вывода на ResponseStream?

Сложение

ViewResultBase.ExecuteResult показывает ViewContext строится с Response.Output, но отладчик показывает ViewContext.Writer как StringWriter

Оба этих подхода результаты в StringWriter

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

EDIT

Оказывается, что System.Web.WebPages.WebPageBaseExecutePageHeirarchy толкает темп StringWriter в стек контекста, так что я не уверен, если это можно обойти

В РЕЗЮМЕ

RenderPartial, RenderAction не напрямую выводить на Response.Stream, ни один из бритвенных Просмотры будет

РЕШЕНИЕ

Это новый движок рендеринга WebPages/Razor, который обертывает все с StringWriter на StringBuilder. Решение состояло в том, чтобы изменить мою страницу, чтобы использовать WebFormViewEngine, который не применяет эту упаковку.

+0

Вместо обновления ответа с решением, было бы более удобным для пользователей, которые ищут подобную проблему, если вы добавите решения в качестве ответа. – vendettamit

ответ

0

Это ниже метода иллюстрирует один из способов достижения этого результата, который вы ищете:

// <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

Это ничем не отличается от ViewResultBase. Моя цель - напрямую выводить на Response.Output и не записывать его в StringBuilder. - Проблема не с MVC, а с System.Web.WebPages.WebPageBase, которая завершает вызов в новый завернутый StringWriter. - Моим конечным решением было использование WebFormViewEngine, которое позволяет напрямую выводить поток ответов – Steve