我有一个 ASP.NET MVC Controller ,其中有一堆返回 ViewResult 的操作方法。现在,我需要能够通过以下方式根据特定的 URL 参数更改操作的结果:
- 如果参数不存在,则直接返回
ViewResult
- 如果该参数存在,则从刚刚执行的操作中获取
ViewResult
,将 View 渲染为字符串,并返回包含该字符串的FileStreamResult
(原始 HTML )+一些附加信息(与问题无关)
我尝试通过重写 Controller 中的 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
。
如何将 View 呈现为字符串?
最佳答案
仅当在 Controller 上下文中执行 View 结果时,
viewResult.View
才会被填充(请参阅 MVC source code 中的 ExecuteResult
方法)。方法 OnActionExecuted
在管道中较早调用,这就是为什么 viewResult.View
在您的情况下为 null
。
您需要做的是使用ViewEngineCollection
手动查找 View ,然后渲染它:
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();
}
}
关于c# - ASP.NET MVC - 修改 OnActionExecuted 中的 View 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39332370/