多次询问将视图呈现给字符串,但我的问题不同。
ViewEngineResult.View
有一个名为Render(ViewContext, TextWriter)
如果我传入包含电子邮件视图的控制器,我的代码工作正常,但是如果操作方法来自另一个控制器,那么我需要能够修改ViewContext以查看EmailControllers视图。
我无法确切地知道Render
方法用于确定要查看的视图文件夹的属性。基本上我想要弄明白这样我可以告诉它查看电子邮件views文件夹。
这是我的参考代码:
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
在Orders视图文件夹中查找我的视图,我需要告诉它查看电子邮件视图文件夹。
答案 0 :(得分:1)
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"
};
所有这些参数都来自RouteData(除非通过View("viewname")
等参数专门覆盖。它们是专门的action
,controller
和area
。通过修改这些参数值可以改变MVC的几种工作方式。包括在选择一个控制器之前确定使用哪个控制器。与动作和区域相同。
希望这有帮助。