在该项目中,该视图有两个文件: ErrorPage.cshtml 和 ErrorPage.Designer.cs .该Designer.cs是如何创建的?它看起来像一个生成的文件.但是,由于它,项目中有一个普通类(ErrorPage)可以显式使用.它从 Microsoft.Extensions.RazorViews.Sources 包继承了 Microsoft.Extensions.RazorViews.BaseView 类.所以中间件只执行该视图: var errorPage =新的ErrorPage(模型);返回errorPage.ExecuteAsync(context); 如何在我的项目中实现?解决方案更新[2018.06]:请注意,该文章是针对.NET Core 2.0编写的,在.NET Core 2.1中RazorEngine的重大更改.原来,这很容易做到.Aspnet prjoect有一个称为 RazorPageGenerator 的内部工具(请参见 https://github.com/aspnet/Razor/tree/dev/src/RazorPageGenerator ),可用于编译视图.使用此工具进行编译后,我们将获得可在中间件中使用的普通类.但是在我们需要获取RazorPageGenerator并对其进行少许自定义之前. 1.创建一个新的控制台项目 dotnet新控制台-o MyRazorGenerator 2.将NuGet.config放入此文件夹 < configuration>< config>< add key ="globalPackagesFolder" value ="./packages"/></config>< packageSources><添加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.restore dotnet restore 来检查您是否拥有RazorPageGenerator 5.添加到 Program.cs : 公共静态int Main(string [] args){if(args == null || args.Length< 1){Console.WriteLine(无效的参数.");返回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结果= RazorPageGenerator.Program.MainCore(razorEngine,targetProjectDirectory);foreach(结果中有var个结果){File.WriteAllText(result.FilePath,result.GeneratedCode);}Console.WriteLine();Console.WriteLine($"{results.Count}文件已成功生成.");Console.WriteLine();返回0;} 6.现在我们有了自己的生成器并可以编译视图 7.创建剃刀视图(.cshtml) 8.运行我们的生成器以编译视图: dotnet运行--project.\ MyRazorPageGenerator \ MyRazorPageGenerator.csproj Croc.XFW3.Web.\ Middleware 在这里,我假设视图位于 Middleware \ Views 文件夹中. 9.Generator创建一个文件,如ErrorPage.Designer.cs(如果视图为ErrorPage.cshtml),我们可以使用: 公共异步任务调用(HttpContext上下文){尝试{等待_next.Invoke(context);如果(context.Response.StatusCode == StatusCodes.Status404NotFound){var statusCodeFeature = context.Features.Get< IStatusCodePagesFeature>();如果(statusCodeFeature == null ||!statusCodeFeature.Enabled){如果(!context.Response.HasStarted){var view = new ErrorPage(new ErrorPageModel());等待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 .I'm working at a middleware for aspnetcore2.0 where I want to execute some razor view.Actually I need a error handling middleware which would show nice pages from razor views. I know that it's possible to do with UseStatusCodePagesWithReExecute based on status codes. But I need a more general approach - handle an exception in my middleware to delegate (in some cases) it to an error view.I realized that DeveloperExceptionPageMiddleware does something similar to what I need. But I can't understand how it works even after digging into its sources.Here is the place where that middleware returns a view - https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNetCore.Diagnostics/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs#L206But I can't understand what kind of view it is. It's nor a razor page (as it has no @page directive) neither an mvc view (but i'm not sure).In the project there're two files for that view: ErrorPage.cshtml and ErrorPage.Designer.cs. How that Designer.cs was created? It looks like a generated file. But thanks to it there's a normal class in the project (ErrorPage) which can be used explicitly. It inherits Microsoft.Extensions.RazorViews.BaseView class from Microsoft.Extensions.RazorViews.Sources package.So the middleware just execute that view:var errorPage = new ErrorPage(model);return errorPage.ExecuteAsync(context);How can it be achieved in my project? 解决方案 UPDATE [2018.06]: Please note that the post was written for .NET Core 2.0 times, there're breaking changes for RazorEngine in .NET Core 2.1.It turned out that it's pretty easy to do.Aspnet prjoect has an internal tool called RazorPageGenerator (see https://github.com/aspnet/Razor/tree/dev/src/RazorPageGenerator) which can be used to compile views. After compilation with this tool we'll get normal classes which can be used in middlewares.But before we need to get RazorPageGenerator and slightly customize it.1.Create a new console projectdotnet new console -o MyRazorGenerator2.put NuGet.config inside this folder<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.Add the following in csprj (as dotnet add package doesn't support installing pre-prelease packages)<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.restore dotnet restore to check you got RazorPageGenerator5.add into 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.Now we have our own generator and can compile views7.Create a Razor View (.cshtml)8.run our generator to compile view:dotnet run --project .\MyRazorPageGenerator\MyRazorPageGenerator.csproj Croc.XFW3.Web .\Middlewarehere I assume that the view is inside Middleware\Views folder.9.Generator creates a file like ErrorPage.Designer.cs (if view was ErrorPage.cshtml) which we can use: 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); } } } } }Here we're returning our view in case of 404 error and absense of StatusCodePagesMiddleware. Can be useful for embedded UI in libs.The generated code uses staff which should be added into your project. To get it we need to acquire nuget package Microsoft.Extensions.RazorViews.Sources. Again it’s not on nuget.org so we need to install it from https://dotnet.myget.org/feed/aspnetcore-dev/package/nuget/Microsoft.Extensions.RazorViews.Sources. 这篇关于aspnetcore:如何从中间件返回视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-16 03:44