使用ICompositeViewEngine的Resolver或ServiceProvider的必需依赖项 [英] Required dependencies for Resolver or ServiceProvider for using ICompositeViewEngine

查看:90
本文介绍了使用ICompositeViewEngine的Resolver或ServiceProvider的必需依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在ASP.NET Core MVC中使用ICompositeViewEngine替换System.Web.Mvc中的ViewEngine,因为它在.NET Core中不再可用.在此项目中,我通常试图将Webform从ASP.NET迁移到ASP.NET Core.

I am trying to use ICompositeViewEngine in ASP.NET Core MVC for substituting ViewEngine from System.Web.Mvc since it is no longer available in .NET Core. I am generally trying to migrate a webform from ASP.NET to ASP.NET Core in this project.

我找到了以下解决方案: MVC 6 Controller中的ControllerContext和ViewEngines属性在哪里?,我相信这可以解决我的问题.我还在github问题中发现了与ServiceProvider相似的引擎创建: https://github.com/aspnet/Mvc/issues/3091

I have found the following solution: Where are the ControllerContext and ViewEngines properties in MVC 6 Controller? and I believe that this may resolve my issue. I have also found a similar engine creation with ServiceProvider in a github question: https://github.com/aspnet/Mvc/issues/3091

但是,由于我对.NET非常陌生,所以我不确定我可能会缺少哪些依赖项或框架.我有以下名称空间:

However, I am not sure about what dependencies or frameworks I may be missing as I am very new with .NET. I have the following namespaces:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.DependencyInjection;

我认为可能与我的问题有关.

That I believe might be related to my issue.

我的原始代码是:

    public static string RenderPartialToString(Controller controller, string viewName, object model)
    {
        controller.ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return "document.write('" + sw.GetStringBuilder().Replace('\n', ' ').Replace('\r', ' ').Replace("'","\\'").ToString() + "');";
        }
    }

现在我正在尝试使用以下两种方式之一:

And now I am trying to use either of the following:

 var engine = Resolver.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
 var engine2 = IServiceProvider.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;

我要解决这个问题吗?是否有更简单的方法来替换.NET Core中的System.Web.Mvc ViewEngines?对于解析器和/或ServiceProvider,我该如何解决"在当前上下文中不存在"错误?

Am I on the right track to fix this? Is there an easier way to replace System.Web.Mvc ViewEngines in .NET Core? What do I need to fix "does not exist in the current context" errors for Resolver and/or ServiceProvider?

谢谢.我希望我能够遵循问题准则.

Thanks. I hope I was able to follow the question guidelines.

请让我知道我是否应该在我的代码中添加此问题的其他内容.我目前正在阅读有关依赖注入的信息,以更好地了解这种情况.

Please let me know if I should include anything else from my code for this question. I am currently reading about Dependency Injection to understand the situation better.

推荐答案

您基本上处于正确的轨道. ASP.NET Core摆脱了许多静态对象,因此您无法执行Resolver.GetService之类的操作. Resolver不存在.而是使用依赖注入系统.

You're mostly on the right track. ASP.NET Core got rid of many static objects so you can't do things like Resolver.GetService. Resolver doesn't exist. Instead, use the dependency injection system.

如果只需要从控制器访问ICompositeViewEngine,则将其注入构造函数中:

If you just need to access ICompositeViewEngine from a controller, inject it in the constructor:

public MyController(ICompositeViewEngine viewEngine)
{
    // save a reference to viewEngine
}

如果您想拥有一个处理从Razor到字符串渲染的离散服务,则需要在启动时进行注册:

If you want to have a discrete service that handles Razor-to-string rendering, you'll need to register it at startup:

public void ConfigureServices(IServiceCollection services)
{
    // (Other code...)

    services.AddTransient<IViewRenderingService, ViewRenderingService>();

    services.AddMvc();
}

服务本身看起来像这样:

The service itself would look like this:

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

public interface IViewRenderingService
{
    string RenderPartialView(ActionContext context, string name, object model = null);
}

public class ViewRenderingService : IViewRenderingService
{
    private readonly ICompositeViewEngine _viewEngine;
    private readonly ITempDataProvider _tempDataProvider;

    public ViewRenderingService(ICompositeViewEngine viewEngine, ITempDataProvider tempDataProvider)
    {
        _viewEngine = viewEngine;
        _tempDataProvider = tempDataProvider;
    }

    public string RenderPartialView(ActionContext context, string name, object model)
    {
        var viewEngineResult = _viewEngine.FindView(context, name, false);

        if (!viewEngineResult.Success)
        {
            throw new InvalidOperationException(string.Format("Couldn't find view '{0}'", name));
        }

        var view = viewEngineResult.View;

        using (var output = new StringWriter())
        {
            var viewContext = new ViewContext(
                context,
                view,
                new ViewDataDictionary(
                    new EmptyModelMetadataProvider(),
                    new ModelStateDictionary())
                {
                    Model = model
                },
                new TempDataDictionary(
                    context.HttpContext,
                    _tempDataProvider),
                output,
                new HtmlHelperOptions());

            view.RenderAsync(viewContext).GetAwaiter().GetResult();

            return output.ToString();
        }
    }
}

要从控制器使用它,请注入并调用它:

To use it from a controller, inject and call it:

public class HomeController : Controller
{
    private readonly IViewRenderingService _viewRenderingService;

    public HomeController(IViewRenderingService viewRenderingService)
    {
        _viewRenderingService = viewRenderingService;
    }

    public IActionResult Index()
    {
        var result = _viewRenderingService.RenderPartialView(ControllerContext, "PartialViewName", model: null);
        // do something with the string

        return View();
    }
}

如果您想完全在MVC之外使用Razor,请参见此答案.

If you want to use Razor outside of MVC entirely, see this answer.

这篇关于使用ICompositeViewEngine的Resolver或ServiceProvider的必需依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆