2017-10-16 90 views
3

我正在爲aspnetcore2.0的中間件工作,我想執行一些剃鬚刀視圖。
其實我需要一個錯誤處理中間件,它將顯示剃鬚刀視圖中的漂亮頁面。我知道根據狀態代碼可以使用UseStatusCodePagesWithReExecute。但是我需要一個更一般的方法 - 在我的中間件中處理一個異常,以便將它委派給某個錯誤視圖(在某些情況下)。aspnetcore:如何從中間件返回視圖

我意識到DeveloperExceptionPageMiddleware做了類似我需要的東西。但是,即使挖掘其資源,我也無法理解它是如何工作的。

這裏是中間件返回一個視圖的地方 - https://github.com/aspnet/Diagnostics/blob/dev/src/Microsoft.AspNetCore.Diagnostics/DeveloperExceptionPage/DeveloperExceptionPageMiddleware.cs#L206

但我不明白它是什麼樣的看法。這也不是剃刀頁(因爲它沒有@page指令)既不是MVC視圖(但我不知道)。

在該項目中,該視圖有兩個文件:ErrorPage.cshtmlErrorPage.Designer.cs。那個Designer.cs是如何創建的?它看起來像一個生成的文件。但感謝它,項目中有一個普通的類(ErrorPage),可以明確地使用它。它從Microsoft.Extensions.RazorViews.Sources包繼承Microsoft.Extensions.RazorViews.BaseView類。

所以中間件只是執行這一觀點:

var errorPage = new ErrorPage(model); 
return errorPage.ExecuteAsync(context); 

怎麼能在我的項目可以實現嗎?

+0

它是否必須是中間件?動作或結果過濾器也可能會這樣做https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters – Tseng

+0

@Tseng主要是因爲它更健壯(中間件可以是管道中的第一個),由於需要處理像404錯誤(他們不是例外,所以mvc過濾器將忽略它們) – Shrike

回答

2

事實證明,這很容易做到。 ASPNET prjoect具有稱爲RazorPageGenerator一個內部工具(見https://github.com/aspnet/Razor/tree/dev/src/RazorPageGenerator),其可以用於編譯的意見。用這個工具編譯後,我們會得到它可以在中間件使用正常上課。

但在此之前,我們需要得到RazorPageGenerator稍微定製。

1,創建一個新的控制檯項目

dotnet new console -o MyRazorGenerator 

2.put 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不支持預安裝-prelease包)

<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檢查你有拉茲orPageGenerator

5.add到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我們有我們自己的發電機,並可以編譯意見

7.Create一個Razor視圖(.cshtml)

8。運行我們的生成器來編譯視圖:

dotnet run --project .\MyRazorPageGenerator\MyRazorPageGenerator.csproj Croc.XFW3.Web .\Middleware 

這裏我假設的看法是Middleware\Views文件夾內。

9.Generator創建像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。對於libs中的嵌入式UI可能很有用。

生成的代碼使用應該添加到項目中的人員。爲了得到它,我們需要獲取nuget包Microsoft.Extensions.RazorViews.Sources。再次,它不在nuget.org上,所以我們需要從https://dotnet.myget.org/feed/aspnetcore-dev/package/nuget/Microsoft.Extensions.RazorViews.Sources進行安裝。

+0

另請參閱我的帖子:https://techblog.dorogin.com/handling-errors-in-aspnet-core-中間件e39872496d51 – Shrike