在项目中,该视图有两个文件:ErrorPage.cshtml 和 ErrorPage.Designer.cs.Designer.cs 是如何创建的?它看起来像一个生成的文件.但是多亏了它,项目中有一个普通的类(ErrorPage)可以显式使用.它从 Microsoft.Extensions.RazorViews.Sources 包中继承了 Microsoft.Extensions.RazorViews.BaseView 类.所以中间件只是执行那个视图:var errorPage = new ErrorPage(model);返回 errorPage.ExecuteAsync(context);如何在我的项目中实现? 解决方案 UPDATE [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 new console -o MyRazorGenerator2.把NuGet.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></配置>3.在csprj中添加以下内容(因为dotnet add package不支持安装预发布包)<PackageReference Include="RazorPageGenerator" Version="2.1.0-*"/><PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.Extensions" 版本="2.1.0-*"/><PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="2.1.0-*"/></项目组>4.restore dotnet restore 检查你是否有 RazorPageGenerator5.加入Program.cs: public static int Main(string[] args){if (args == null || 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.创建 Razor 视图 (.cshtml)8.运行我们的生成器来编译视图:dotnet run --project .MyRazorPageGeneratorMyRazorPageGenerator.csproj Croc.XFW3.Web .Middleware这里我假设视图位于 MiddlewareViews 文件夹内.9.Generator 创建一个类似 ErrorPage.Designer.cs 的文件(如果视图是 ErrorPage.cshtml),我们可以使用: 公共异步任务调用(HttpContext 上下文){尝试{等待_next.Invoke(上下文);if (context.Response.StatusCode == StatusCodes.Status404NotFound){var statusCodeFeature = context.Features.Get();if (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 .MyRazorPageGeneratorMyRazorPageGenerator.csproj Croc.XFW3.Web .Middlewarehere I assume that the view is inside MiddlewareViews 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