将视图呈现为字符串已经被问了很多次,但我的问题有所不同。
ViewEngineResult.View
有一个名为Render(ViewContext, TextWriter)
的方法
如果我传入包含我的电子邮件视图的控制器,我的代码工作正常,但是如果操作方法源自另一个控制器,那么我需要能够修改 ViewContext 以查看电子邮件控制器视图。
我无法确切地弄清楚 Render
方法使用什么属性来确定要查看哪些视图文件夹。从本质上讲,我希望弄清楚这一点,以便我可以告诉它查看电子邮件视图文件夹。
这是我的代码供参考:
public static string RenderPartialViewToString(Controller controller, string viewName, object model)
{
var oldModel = controller.ViewData.Model;
controller.ViewData.Model = model;
try
{
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName,
null);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
controller.ViewData.Model = oldModel;
return sw.GetStringBuilder().ToString();
}
}
catch (Exception ex)
{
throw ex;
}
}
所以回顾一下,如果我传入订单控制器,FindView
在订单视图文件夹中查找我的视图,我需要告诉它在电子邮件视图文件夹中查找。
ViewEngine 查看RouteData
以确定要加载.cshtml
文件。特别是controller
和action
属性。您可以(并且可能建议)传入您要使用的控制器名称,但您可以看到我已经在下面的代码中将其硬编码为现在Email
。
public static string RenderPartialViewToString(Controller controller, string viewName, object model)
{
var oldModel = controller.ViewData.Model;
controller.ViewData.Model = model;
try
{
using (var sw = new StringWriter())
{
controller.RouteData.Values["controller"] = "Email";
var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, null);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
controller.ViewData.Model = oldModel;
return sw.GetStringBuilder().ToString();
}
}
catch (Exception ex)
{
throw ex;
}
}
如果你真的想知道,还有更多的东西
Razor 在尝试确定要使用的视图时会查找多个位置。 {0}
这里是操作(或传入视图名称),{1}
是控制器。
ViewLocationFormats = new[] {
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/{0}.vbhtml",
"~/Views/Shared/{0}.cshtml",
"~/Views/Shared/{0}.vbhtml"
};
和这里一样,除了我们也{2}
这是该地区。
AreaViewLocationFormats = new[] {
"~/Areas/{2}/Views/{1}/{0}.cshtml",
"~/Areas/{2}/Views/{1}/{0}.vbhtml",
"~/Areas/{2}/Views/Shared/{0}.cshtml",
"~/Areas/{2}/Views/Shared/{0}.vbhtml"
};
所有这些参数都来自路由数据(除非通过 View("viewname")
等参数明确覆盖。它们特别action
、controller
和area
。通过修改这些值,可以更改 MVC 的多种工作方式。包括在选择控制器之前确定要使用的控制器。操作和区域相同。
希望这有帮助。