我有一个ASP.NET MVC控制器,其中包含许多返回ViewResult的操作方法。现在,我需要能够通过以下方式根据某个URL参数更改操作的结果:
ViewResult
ViewResult
,将视图渲染为字符串,然后返回包含此字符串的FileStreamResult
(原始HTML)+一些其他信息(与问题无关)我试图通过覆盖控制器中的OnActionExecuted
来做到这一点:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
var viewResult = filterContext.Result as ViewResult;
if (viewResult != null /* && certain URL param present*/)
{
string rawHtml = RenderViewIntoString(viewResult);
filterContext.Result = new FileStreamResult(new MemoryStream(Encoding.UTF8.GetBytes(rawHtml)), "application/octet-stream");
}
}
但是我无法找到实施RenderViewIntoString
的方法,因为出于某种原因,viewResult.View
在这里null
。
如何在此处将视图渲染为字符串?
答案 0 :(得分:2)
viewResult.View
(请参阅MVC source code中的ExecuteResult
方法)。方法OnActionExecuted
在流程管理系统的前面调用,这就是为什么viewResult.View
在您的情况下为null
。
您需要做的是使用ViewEngineCollection
手动查找视图,然后呈现它:
private static string RenderViewIntoString(ViewResult viewResult, ActionExecutedContext filterContext)
{
string viewName = !string.IsNullOrEmpty(viewResult.ViewName) ? viewResult.ViewName : filterContext.ActionDescriptor.ActionName;
IView view = viewResult.ViewEngineCollection.FindView(filterContext.Controller.ControllerContext, viewName, viewResult.MasterName).View;
if (view == null)
{
throw new InvalidOperationException($"The view '{viewName}' or its master was not found");
}
using (var stringWriter = new StringWriter())
{
var viewContext = new ViewContext(filterContext.Controller.ControllerContext, view, filterContext.Controller.ViewData, filterContext.Controller.TempData, stringWriter);
view.Render(viewContext, stringWriter);
return stringWriter.ToString();
}
}