MVC 6 Controller中的ControllerContext和ViewEngines属性在哪里?

我创建了一个新的MVC6项目并构建了一个新站点。 目标是获取视图的渲染结果。 我找到了以下代码,但我无法让它工作,因为我找不到ControllerContextViewEngines

这是我想要重写的代码:

 protected string RenderPartialViewToString(string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.RouteData.GetRequiredString("action"); ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } 

更新 :我正在更新这个以与.Net Core 2.x一起使用,因为API自2015年以来已发生变化!

首先,我们可以利用ASP.Net MVC Core附带的内置dependency injection,它将为我们提供手动渲染视图所需的ICompositeViewEngine对象。 例如,控制器看起来像这样:

 public class MyController : Controller { private ICompositeViewEngine _viewEngine; public MyController(ICompositeViewEngine viewEngine) { _viewEngine = viewEngine; } //Rest of the controller code here } 

接下来,我们实际需要呈现视图的代码。 请注意,现在是async方法,因为我们将在内部进行异步调用:

 private async Task RenderPartialViewToString(string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.ActionDescriptor.ActionName; ViewData.Model = model; using (var writer = new StringWriter()) { ViewEngineResult viewResult = _viewEngine.FindView(ControllerContext, viewName, false); ViewContext viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, writer, new HtmlHelperOptions() ); await viewResult.View.RenderAsync(viewContext); return writer.GetStringBuilder().ToString(); } } 

要调用该方法,它就像这样简单:

 public async Task Index() { var model = new TestModel { SomeProperty = "whatever" } var renderedView = await RenderPartialViewToString("NameOfView", model); //Do what you want with the renderedView here return View(); } 

已发布的dotnet核心1.0已更改,上述代码的此版本适用于1.0 RTM。

 protected string RenderPartialViewToString(string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = ControllerContext.ActionDescriptor.DisplayName; ViewData.Model = model; using (StringWriter sw = new StringWriter()) { var engine = _serviceProvider.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine; // Resolver.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine; ViewEngineResult viewResult = engine.FindView(ControllerContext, viewName, false); ViewContext viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, sw, new HtmlHelperOptions() //Added this parameter in ); //Everything is async now! var t = viewResult.View.RenderAsync(viewContext); t.Wait(); return sw.GetStringBuilder().ToString(); } } 

编译此代码需要这些用法:

 using System.IO; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures; 

我还必须在控制器构造函数中添加一个DI接口:

 IServiceProvider serviceProvider 

我的帐户构造函数现在看起来像这样:

 public AccountController( UserManager userManager, SignInManager signInManager, IEmailSender emailSender, ISmsSender smsSender, ILoggerFactory loggerFactory, IServiceProvider serviceProvider) { _userManager = userManager; _signInManager = signInManager; _emailSender = emailSender; _smsSender = smsSender; _logger = loggerFactory.CreateLogger(); _serviceProvider = serviceProvider; } 

Martin Tomes提供的解决方案为我工作但我必须更换:

 ViewEngineResult viewResult = engine.FindView(ControllerContext, viewName, false); 

 ViewEngineResult viewResult = engine.GetView(_env.WebRootPath, viewName, false); 

另外在控制器构造函数中也要添加

 private IHostingEnvironment _env; public AccountController(IHostingEnvironment env) { _env = env; } 

Martin Tomes的解决方案效果很好。 我的更改:删除了serviceProvider并通过DI在构造函数中获取ICompositeViewEngine。 构造函数看起来像:

 private readonly ICompositeViewEngine _viewEngine; public AccountController( UserManager userManager, SignInManager signInManager, IEmailSender emailSender, ISmsSender smsSender, ILoggerFactory loggerFactory, ICompositeViewEngine viewEngine) { _userManager = userManager; _signInManager = signInManager; _emailSender = emailSender; _smsSender = smsSender; _logger = loggerFactory.CreateLogger(); _viewEngine = viewEngine;; } 

并把

 ViewEngineResult viewResult = _viewEngine.FindView(ControllerContext, viewName, false); 

代替

 var engine = _serviceProvider.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine; // Resolver.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine; ViewEngineResult viewResult = engine.FindView(ControllerContext, viewName, false);