Resolver或ServiceProvider使用ICompositeViewEngine所需的依赖项
我试图在ASP.NET Core MVC中使用ICompositeViewEngine替换System.Web.Mvc中的ViewEngine,因为它在.NET Core中不再可用。 我通常尝试在此项目中将webform从ASP.NET迁移到ASP.NET Core。
我找到了以下解决方案: MVC 6 Controller中的ControllerContext和ViewEngines属性在哪里? 我相信这可以解决我的问题。 我还在github问题中找到了与ServiceProvider类似的引擎创建: 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.DependencyInjection;
我认为这可能与我的问题有关。
我原来的代码是:
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;
我是否正确地解决这个问题? 有没有更简单的方法来替换.NET Core中的System.Web.Mvc ViewEngines? 解析器和/或ServiceProvider需要修复哪些“ 当前上下文中不存在 ”错误?
谢谢。 我希望我能够遵循问题指南。
编辑:如果我在此代码中包含其他任何内容,请告诉我。 我目前正在阅读有关dependency injection的信息,以便更好地了解情况。
你大部分时间都在正确的轨道上。 ASP.NET Core摆脱了许多静态对象,因此您无法执行Resolver.GetService
。 Resolver
不存在。 相反,使用dependency injection系统。
如果您只需要从控制器访问ICompositeViewEngine
,请将其注入构造函数:
public MyController(ICompositeViewEngine viewEngine) { // save a reference to viewEngine }
如果你想拥有一个处理Razor-to-string渲染的离散服务,你需要在启动时注册它:
public void ConfigureServices(IServiceCollection services) { // (Other code...) services.AddTransient(); services.AddMvc(); }
服务本身看起来像这样:
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(); } }
如果你想完全在MVC之外使用Razor,请参阅这个答案 。