更新[2018.06]: 请注意,此文章是针对.NET Core 2.0编写的,而在.NET Core 2.1中,RazorEngine存在重大变化。
事实证明这很容易实现。Aspnet项目有一个名为RazorPageGenerator
的内部工具(参见https://github.com/aspnet/Razor/tree/dev/src/RazorPageGenerator),它可以用于编译视图。使用此工具进行编译后,我们将得到可用于中间件的普通类。
但在此之前,我们需要获取RazorPageGenerator并进行轻微的自定义。
1.创建一个新的控制台项目。
dotnet new console -o MyRazorGenerator
2.将NuGet.config放置于此文件夹中。
<configuration>
<config>
<add key="globalPackagesFolder" value="./packages" />
</config>
<packageSources>
<add key="aspnetcore-dev" value="https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json " />
</packageSources>
</configuration>
3.在csprj中添加以下内容(因为dotnet add package
不支持安装预发布包)
<ItemGroup>
<PackageReference Include="RazorPageGenerator" Version="2.1.0-*" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions" Version="2.1.0-*" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="2.1.0-*" />
</ItemGroup>
4.恢复dotnet restore
以检查您是否已获得RazorPageGenerator。
5.添加到Program.cs
:
public static int Main(string[] args)
{
if (args == null || args.Length < 1)
{
Console.WriteLine("Invalid argument(s).");
return 1;
}
var rootNamespace = args[0];
var targetProjectDirectory = args.Length > 1 ? args[1] : Directory.GetCurrentDirectory();
var razorEngine = RazorPageGenerator.Program.CreateRazorEngine(rootNamespace, builder => {
FunctionsDirective.Register(builder);
InheritsDirective.Register(builder);
SectionDirective.Register(builder);
});
var results = RazorPageGenerator.Program.MainCore(razorEngine, targetProjectDirectory);
foreach (var result in results)
{
File.WriteAllText(result.FilePath, result.GeneratedCode);
}
Console.WriteLine();
Console.WriteLine($"{results.Count} files successfully generated.");
Console.WriteLine();
return 0;
}
6.现在我们有了自己的生成器,可以编译视图。
7.创建一个 Razor 视图 (.cshtml)。
8.运行我们的生成器来编译视图:
dotnet run --project .\MyRazorPageGenerator\MyRazorPageGenerator.csproj Croc.XFW3.Web .\Middleware
我假设这个视图在 Middleware\Views
文件夹中。
9.生成器会创建一个类似于 ErrorPage.Designer.cs 的文件(如果视图是 ErrorPage.cshtml),我们可以使用它:
public async Task Invoke(HttpContext context)
{
try
{
await _next.Invoke(context);
if (context.Response.StatusCode == StatusCodes.Status404NotFound)
{
var statusCodeFeature = context.Features.Get<IStatusCodePagesFeature>();
if (statusCodeFeature == null || !statusCodeFeature.Enabled)
{
if (!context.Response.HasStarted)
{
var view = new ErrorPage(new ErrorPageModel());
await view.ExecuteAsync(context);
}
}
}
}
}
如果出现404错误和缺少StatusCodePagesMiddleware,我们将返回我们的视图。这对嵌入式UI库可能很有用。
生成的代码使用需要添加到您的项目中的工具。为了获取它,我们需要获取nuget包Microsoft.Extensions.RazorViews.Sources。同样,它不在nuget.org上,因此我们需要从https://dotnet.myget.org/feed/aspnetcore-dev/package/nuget/Microsoft.Extensions.RazorViews.Sources安装它。