Необходимые зависимости для Resolver или ServiceProvider для использования ICompositeViewEngine

Я пытаюсь использовать ICompositeViewEngine в ASP.NET Core MVC для замены ViewEngine из System.Web.Mvc, поскольку он больше не доступен в .NET Core. Обычно я пытаюсь перенести веб-форму с ASP.NET на ASP.NET Core в этом проекте.

Я нашел следующее решение: Где находятся свойства ControllerContext и ViewEngines в MVC 6 Controller?, и я считаю, что это может решить мою проблему. Я также нашел аналогичное создание двигателя с ServiceProvider в вопросе github: https://github.com/aspnet/Mvc/issues/3091

Однако я не уверен в том, какие зависимости или рамки я могу потерять, поскольку я очень новичок в .NET. У меня есть следующие пространства имен:

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

Я считаю, что это может быть связано с моей проблемой.

Мой исходный код:

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() + "');";
 }
 }

И теперь я пытаюсь использовать одно из следующих:

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

Я на правильном пути, чтобы исправить это? Есть ли более простой способ заменить System.Web.Mvc ViewEngines в .NET Core? Что мне нужно для исправления " не существует в текущем контексте" для Resolver и/или ServiceProvider?

Спасибо. Надеюсь, я смог следовать рекомендациям по вопросам.

Изменить: Пожалуйста, дайте мне знать, если я должен включить что-нибудь еще из моего кода для этого вопроса. В настоящее время я читаю об Injection Dependency, чтобы лучше понять ситуацию.

1 ответ

Ты в основном на правильном пути. ASP.NET Core избавился от многих статических объектов, поэтому вы не можете делать такие вещи, как Resolver.GetService. Resolver не существует. Вместо этого используйте систему впрыскивания.

Если вам просто нужно получить доступ к ICompositeViewEngine от контроллера, введите его в конструктор:

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

Если вы хотите иметь дискретный сервис, который обрабатывает рендеринг Razor-to-string, вам нужно зарегистрировать его при запуске:

public void ConfigureServices(IServiceCollection services)
{
 // (Other code...)
 services.AddTransient<iviewrenderingservice, viewrenderingservice="">();
 services.AddMvc();
}
</iviewrenderingservice,>

Сама служба будет выглядеть так:

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();
 }
 }
}

Чтобы использовать его с контроллера, введите и вызовите его:

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();
 }
}

Если вы хотите полностью использовать Razor вне MVC, см. этот ответ.

licensed under cc by-sa 3.0 with attribution.