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

Mar*_*ijn 17 c# asp.net-mvc asp.net-core-mvc asp.net-core

我创建了一个新的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*idG 22

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

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

public class MyController : Controller
{
    private ICompositeViewEngine _viewEngine;

    public MyController(ICompositeViewEngine viewEngine)
    {
        _viewEngine = viewEngine;
    }

    //Rest of the controller code here
}
Run Code Online (Sandbox Code Playgroud)

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

private async Task<string> 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public async Task<IActionResult> Index()
{
    var model = new TestModel
    {
        SomeProperty = "whatever"
    }

    var renderedView = await RenderPartialViewToString("NameOfView", model);

    //Do what you want with the renderedView here

    return View();
}
Run Code Online (Sandbox Code Playgroud)


小智 14

已发布的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

using System.IO;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
Run Code Online (Sandbox Code Playgroud)

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

IServiceProvider serviceProvider
Run Code Online (Sandbox Code Playgroud)

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

public AccountController(
    UserManager<ApplicationUser> userManager,
    SignInManager<ApplicationUser> signInManager,
    IEmailSender emailSender,
    ISmsSender smsSender,
    ILoggerFactory loggerFactory,
    IServiceProvider serviceProvider)
{
    _userManager = userManager;
    _signInManager = signInManager;
    _emailSender = emailSender;
    _smsSender = smsSender;
    _logger = loggerFactory.CreateLogger<AccountController>();
    _serviceProvider = serviceProvider;
}
Run Code Online (Sandbox Code Playgroud)

  • 通过提供的引用,我收到“名称'ViewData'在当前上下文中不存在”。与TempData相同。 (2认同)