Kai*_*ite 5 razorengine asp.net-core-mvc asp.net-core
在我的 asp.net core 项目中,我尝试使用以下方法查找 Razor 视图:
private IView FindView(ActionContext actionContext, string viewName)
{
var getViewResult = _viewEngine.GetView(executingFilePath: null, viewPath: viewName, isMainPage: true);
if (getViewResult.Success)
{
return getViewResult.View;
}
var findViewResult = _viewEngine.FindView(actionContext, viewName, isMainPage: true);
if (findViewResult.Success)
{
return findViewResult.View;
}
var searchedLocations = getViewResult.SearchedLocations.Concat(findViewResult.SearchedLocations);
var errorMessage = string.Join(
Environment.NewLine,
new[] { $"Unable to find view '{viewName}'. The following locations were searched:" }.Concat(searchedLocations));
throw new InvalidOperationException(errorMessage);
}
Run Code Online (Sandbox Code Playgroud)
在哪里
viewName = "Views/Email/ResetPassword.cshtml"
Run Code Online (Sandbox Code Playgroud)
是_viewEngine,IRazorViewEngine但没有找到任何。
我的项目结构:
IView.FindView方法是从 Business 调用的。
我还有另一个项目,它具有项目结构并使用相同的方法来检索视图,更重要的是,它找到了这个视图,但它使用 netcoreapp2.2,而我当前的项目使用 netcoreapp3.1 (Microsoft.AspNetCore.Mvc .Razor 版本相同 - 2.2.0)。
为什么这个方法找不到.net core 3.1上的视图?
更新
两个项目都会将此 Views 文件夹复制到Api\bin\Debug\netcoreapp{version}构建时的文件夹中。
虽然我是在 Core 3.1 中从头开始构建的,并且没有从早期版本升级,但我遇到了同样的问题。我通过执行以下操作使事情正常进行:
我创建了一个实现IWebHostEnvironment(我称之为我的DummyWebHostEnvironment.cs)。我将接口的除一个属性之外的所有属性都保留为默认实现;对于该属性,我使用了包含视图的项目的名称。(为了简洁起见,我只是将其硬编码到下面的示例中;显然有更灵活的方法来获取它。)
public class DummyWebHostEnvironment : IWebHostEnvironment
{
public IFileProvider WebRootFileProvider { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string WebRootPath { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string ApplicationName { get => "TheProjectContainingMyViews.RazorClassLibrary"; set => throw new System.NotImplementedException(); }
public IFileProvider ContentRootFileProvider { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string ContentRootPath { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
public string EnvironmentName { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
}
Run Code Online (Sandbox Code Playgroud)
注意:从上面的代码可以明显看出,包含视图的项目是一个 RazorClassLibrary。(我使用这个和这个作为让 RazorViewEngine 在控制台应用程序中工作的指南。)
我有上面的实现,我将它与其他一些好东西一起添加到我的服务集合中:
private static RazorViewToStringRenderer GetRenderer()
{
var services = new ServiceCollection();
var applicationEnvironment = PlatformServices.Default.Application;
services.AddSingleton(applicationEnvironment);
var appDirectory = Directory.GetCurrentDirectory();
var environment = new DummyWebHostEnvironment();
services.AddSingleton<IWebHostEnvironment>(environment);
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<DiagnosticSource>(diagnosticSource);
services.AddSingleton<DiagnosticListener>(diagnosticSource);
services.AddLogging();
services.AddMvc();
services.AddSingleton<RazorViewToStringRenderer>();
var provider = services.BuildServiceProvider();
return provider.GetRequiredService<RazorViewToStringRenderer>();
}
Run Code Online (Sandbox Code Playgroud)
注意:请参阅上面第一个链接的代码RazorViewToStringRenderer。这是界面:
public interface IRazorViewToStringRenderer
{
Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model);
}
Run Code Online (Sandbox Code Playgroud)
然后,在 中Program.cs,我可以做这样的事情:
static async Task Main(string[] args)
{
var dto = BuildDto();
var renderer = GetRenderer();
var renderedString = await renderer.RenderViewToStringAsync("Views/Path/To/Some.cshtml", dto);
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4302 次 |
| 最近记录: |