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,它允许直接输出到响应流,而不是使用解决方案更新答案,如果您将解决方案添加为答案,则对于寻求类似问题的用户来说会更方便。