Asp.net mvc Mvc渲染操作/部分响应输出

Asp.net mvc Mvc渲染操作/部分响应输出,asp.net-mvc,html.renderpartial,Asp.net Mvc,Html.renderpartial,尽管@Html.RenderPartial调用write并返回void,但它仍在向StringWriter/StringBuilder写入。有没有一种方法可以直接渲染到ResponseStream 这可以通过一个自定义的IViewEngine来实现吗?该引擎实现了类似于PdfView的渲染,直接输出到响应流 添加 ViewResultBase.ExecuteResult显示正在使用Response.Output生成的ViewContext,但调试器将ViewContext.Writer显示为St

尽管
@Html.RenderPartial
调用write并返回
void
,但它仍在向
StringWriter
/
StringBuilder
写入。有没有一种方法可以直接渲染到
ResponseStream

这可以通过一个自定义的
IViewEngine
来实现吗?该引擎实现了类似于
PdfView的渲染,直接输出到
响应流

添加

ViewResultBase.ExecuteResult
显示正在使用
Response.Output
生成的
ViewContext
,但调试器将
ViewContext.Writer
显示为
StringWriter

return PartialView("view", Model)
// or
PartialView("view", Model).ExecuteResult(ControllerContext)
这两种方法都会产生
StringWriter

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

似乎
System.Web.WebPages.WebPageBase
executePageHierarchy
将临时
StringWriter
推送到上下文堆栈上,因此我不确定是否可以绕过它

总之

RenderPartial,RenderAction不会直接输出到响应。Stream,Razor视图都不会

解决方案


新的网页/Razor呈现引擎将所有内容用
StringWriter
包装成
StringBuilder
。解决方案是将我的页面更改为使用不应用此包装的
WebFormViewEngine

下面的方法说明了实现您想要的结果的一种方法:

// <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;
        }
//
//将模型/视图渲染为流的扩展方法
// 
//尝试渲染到流的模型
//这将来自您的执行操作
// 
公共静态流GetStream(CustomModel myModel、ControllerBase ControllerBase)
{
//我们将返回此流
MemoryStream stream=新的MemoryStream();
//可以向视图数据中添加变量
controllerBase.ViewData[“ViewDataVariable1”]=true;
//设定你的模型
controllerBase.ViewData.Model=myModel;
//该示例使用UTF-8编码,如果使用其他编码,则应更改该编码。
//写入流
使用(StreamWriter=newstreamwriter(stream,Encoding.UTF8))
{
使用(var sw=new StringWriter())
{
//呈现视图~/Views/Shared/_FeedbackMessage.cshtml(如果希望使其超通用,可以作为参数传入)
var viewResult=ViewEngines.Engines.FindPartialView(controllerBase.ControllerContext,“_FeedbackMessage”);
//创建新的视图上下文
var viewContext=新的viewContext(controllerBase.ControllerContext,viewResult.View,controllerBase.ViewData,controllerBase.TempData,sw);
//渲染viewengine,让razor发挥它的魔力
viewResult.View.Render(viewContext,sw);
viewResult.ViewEngine.ReleaseView(controllerBase.ControllerContext,viewResult.View);
//从StringWriter sw获取StringBuilder并写入流编写器
//如果您感兴趣的话,可以在这里返回StringWriter
Write(sw.GetStringBuilder().ToString());
writer.Flush();
流位置=0;
}
}
//从上述进程返回流
回流;
}

这与ViewResultBase没有什么不同。我的目标是直接输出到Response.output,而不是在StringBuilder中捕获它。-问题不在于MVC,而在于System.Web.WebPages.WebPageBase,它将调用包装到新包装的StringWriter中。-我的最终解决方案是使用WebFormViewEngine,它允许直接输出到响应流,而不是使用解决方案更新答案,如果您将解决方案添加为答案,则对于寻求类似问题的用户来说会更方便。