无法解析类型 Microsoft.AspNetCore.Mvc.Razor.IRazorViewEngine 的服务
Unable to resolve service for type Microsoft.AspNetCore.Mvc.Razor.IRazorViewEngine
在我的 core 2.2
项目中,我有返回 Razor View
作为字符串的标准服务(我需要它在我用 WPF
编写的客户端中生成 pdf):
public class RaportService : IRaportService
{
private readonly IProjectRepository projectRepository;
private readonly IRazorViewEngine razorViewEngine;
private readonly ITempDataProvider tempDataProvider;
private readonly IServiceProvider serviceProvider;
public RaportService(
IProjectRepository projectRepository,
IRazorViewEngine razorViewEngine,
ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider)
{
this.projectRepository = projectRepository;
this.razorViewEngine = razorViewEngine;
this.tempDataProvider = tempDataProvider;
this.serviceProvider = serviceProvider;
}
public async Task<string> GenerateProjectRaport(int projectId)
{
var project = await this.projectRepository.GetProjectWithTasksAsync(projectId)
?? throw new EntityNotFoundException();
var httpContext = new DefaultHttpContext { RequestServices = this.serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
using (var stringWriter = new StringWriter())
{
string viewPath = "~/wwwroot/RaportTemplate.cshtml";
var viewResult = this.razorViewEngine.GetView(viewPath, viewPath, false);
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = new RaportViewModel
{
Project = project,
ProjectTasks = project.Tasks.ToList(),
ProjectEndedTasks = project.EndedTasks.ToList(),
}
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, this.tempDataProvider),
stringWriter,
new HtmlHelperOptions());
await viewResult.View.RenderAsync(viewContext);
return stringWriter.ToString();
}
}
}
在 Core 2.2
中一切正常。当我将项目更新为 Core 3.0
时,出现此错误:
{
"stackTrace":" at MediatR.Internal.RequestHandlerBase.GetHandler[THandler](ServiceFactory factory)\r\n
at MediatR.Internal.RequestHandlerWrapperImpl`2.<>c__DisplayClass0_0.<Handle>g__Handler|0()\r\n at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n
at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n
at TaskManager.Api.Controllers.RaportController.GetProjectRaport(Int32 projectId) in C:\Users\Michał\Source\Repos\michasacuer\TaskManager\Src\Web\TaskManager.Api\Controllers\RaportController.cs:line 12\r\n at lambda_method(Closure , Object )\r\n
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)",
"message":"Error constructing handler for request of type MediatR.IRequestHandler`2[TaskManager.Application.Raport.Queries.GetProjectRaport.GetProjectRaportQuery,System.String]. Register your handlers with the container. See the samples in GitHub for examples."}
即使我在 Startup
中注册 IRazorViewEngine
接口和 class 它仍然抛出,他需要调用 IRazorPageFactoryProvider
的东西但我不知道,什么是它的一个实现。
那么如何让 Razor View Engine 与 .NET Core 3.0
一起工作?
我找到了解决方案。当您想在 .Net Core 3.0
中访问 RazorViewEngine
时(尤其是在 Web Api 中)将这两行添加到您的 Startup.cs
:
services.AddControllersWithViews();
services.AddRazorPages();
解决方法是添加所需的服务。下面的代码完成了这项工作。在 Startup.cs 中,诀窍是从 AddMvcCore()
或 AddMvc
中获取 builder
,然后调用 AddRazorViewEngine
var builder = services.AddMvcCore();
builder.AddRazorViewEngine();
如果您只想访问 RazorViewEngine
,您可以使用 AddMvcCore().AddRazorViewEngine()
。现在只要使用 DI
就可以随心所欲地访问它
public void ConfigureServices(IServiceCollection services) {
...
services.AddMvcCore().AddRazorViewEngine();
}
在我的 core 2.2
项目中,我有返回 Razor View
作为字符串的标准服务(我需要它在我用 WPF
编写的客户端中生成 pdf):
public class RaportService : IRaportService
{
private readonly IProjectRepository projectRepository;
private readonly IRazorViewEngine razorViewEngine;
private readonly ITempDataProvider tempDataProvider;
private readonly IServiceProvider serviceProvider;
public RaportService(
IProjectRepository projectRepository,
IRazorViewEngine razorViewEngine,
ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider)
{
this.projectRepository = projectRepository;
this.razorViewEngine = razorViewEngine;
this.tempDataProvider = tempDataProvider;
this.serviceProvider = serviceProvider;
}
public async Task<string> GenerateProjectRaport(int projectId)
{
var project = await this.projectRepository.GetProjectWithTasksAsync(projectId)
?? throw new EntityNotFoundException();
var httpContext = new DefaultHttpContext { RequestServices = this.serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
using (var stringWriter = new StringWriter())
{
string viewPath = "~/wwwroot/RaportTemplate.cshtml";
var viewResult = this.razorViewEngine.GetView(viewPath, viewPath, false);
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = new RaportViewModel
{
Project = project,
ProjectTasks = project.Tasks.ToList(),
ProjectEndedTasks = project.EndedTasks.ToList(),
}
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, this.tempDataProvider),
stringWriter,
new HtmlHelperOptions());
await viewResult.View.RenderAsync(viewContext);
return stringWriter.ToString();
}
}
}
在 Core 2.2
中一切正常。当我将项目更新为 Core 3.0
时,出现此错误:
{
"stackTrace":" at MediatR.Internal.RequestHandlerBase.GetHandler[THandler](ServiceFactory factory)\r\n
at MediatR.Internal.RequestHandlerWrapperImpl`2.<>c__DisplayClass0_0.<Handle>g__Handler|0()\r\n at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n
at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n
at TaskManager.Api.Controllers.RaportController.GetProjectRaport(Int32 projectId) in C:\Users\Michał\Source\Repos\michasacuer\TaskManager\Src\Web\TaskManager.Api\Controllers\RaportController.cs:line 12\r\n at lambda_method(Closure , Object )\r\n
at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)",
"message":"Error constructing handler for request of type MediatR.IRequestHandler`2[TaskManager.Application.Raport.Queries.GetProjectRaport.GetProjectRaportQuery,System.String]. Register your handlers with the container. See the samples in GitHub for examples."}
即使我在 Startup
中注册 IRazorViewEngine
接口和 class 它仍然抛出,他需要调用 IRazorPageFactoryProvider
的东西但我不知道,什么是它的一个实现。
那么如何让 Razor View Engine 与 .NET Core 3.0
一起工作?
我找到了解决方案。当您想在 .Net Core 3.0
中访问 RazorViewEngine
时(尤其是在 Web Api 中)将这两行添加到您的 Startup.cs
:
services.AddControllersWithViews();
services.AddRazorPages();
解决方法是添加所需的服务。下面的代码完成了这项工作。在 Startup.cs 中,诀窍是从 AddMvcCore()
或 AddMvc
中获取 builder
,然后调用 AddRazorViewEngine
var builder = services.AddMvcCore();
builder.AddRazorViewEngine();
如果您只想访问 RazorViewEngine
,您可以使用 AddMvcCore().AddRazorViewEngine()
。现在只要使用 DI
public void ConfigureServices(IServiceCollection services) {
...
services.AddMvcCore().AddRazorViewEngine();
}