溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在asp.net core的中間件中返回具體的頁面

發(fā)布時間:2021-12-06 11:53:32 來源:億速云 閱讀:118 作者:iii 欄目:云計算

這篇文章主要講解了“怎么在asp.net core的中間件中返回具體的頁面”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么在asp.net core的中間件中返回具體的頁面”吧!

前言

在 asp.net core 中,存在著中間件這一概念,在中間件中,我們可以比過濾器更早的介入到 http 請求管道,從而實現(xiàn)對每一次的 http 請求、響應做切面處理,從而實現(xiàn)一些特殊的功能

在使用中間件時,我們經(jīng)常實現(xiàn)的是鑒權、請求日志記錄、全局異常處理等等這種非業(yè)務性的需求,而如果你有在 asp.net core 中使用過 swashbuckle(swagger)、health check、mini profiler 等等這樣的組件的話,你會發(fā)現(xiàn),這些第三方的組件往往都提供了頁面,允許我們通過可視化的方式完成某些操作或瀏覽某些數(shù)據(jù)

Step by Step

最終實現(xiàn)的功能其實很簡單,當用戶跳轉到某個指定的地址后,自定義的中間件通過匹配到該路徑,從而返回指定的頁面,所以這里主要會涉及到中間件是如何創(chuàng)建,以及如何處理頁面中的靜態(tài)文件引用

因為這塊并不會包含很多的代碼,所以這里主要是通過分析 Swashbuckle.AspNetCore 的代碼,了解它是如何實現(xiàn)的這一功能,從而給我們的功能實現(xiàn)提供一個思路

在 asp.net core 中使用 Swashbuckle.AspNetCore 時,我們通常需要在 Startup 類中針對組件做如下的配置,根據(jù)當前程序的信息生成 json 文件 =》 公開生成的 json 文件地址 =》 根據(jù) json 文件生成可視化的交互頁面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Startup
{
   // This method gets called by the runtime. Use this method to add services to the container.
   public void ConfigureServices(IServiceCollection services)
   {
       // 生成 swagger 配置的 json 文件
       services.AddSwaggerGen(s =>
       {
           s.SwaggerDoc("v1", new OpenApiInfo
           {
               Contact = new OpenApiContact
               {
                   Name = "Danvic Wang",
                   Url = new Uri("https://yuiter.com"),
               },
               Description = "Template.API - ASP.NET Core 后端接口模板",
               Title = "Template.API",
               Version = "v1"
           });

           // 參數(shù)使用駝峰的命名方式
           s.DescribeAllParametersInCamelCase();
       });
   }

   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
   public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
   {
       // 公開 swagger 生成的 json 文件節(jié)點
       app.UseSwagger();

       // 啟用 swagger 可視化交互頁面
       app.UseSwaggerUI(s =>
       {
           s.SwaggerEndpoint($"/swagger/v1/swagger.json",
               $"Swagger doc v1");
       });
   }
}

可以看到最終呈現(xiàn)給用戶的頁面,其實是在 Configure 方法中通過調用 UseSwaggerUI 方法來完成的,這個方法是在 Swashbuckle.AspNetCore.SwaggerUI 這個程序集中,所以這里直接從 github 上找到對應的文件夾,clone 下源代碼,來看下是如何實現(xiàn)在中間件中返回特定的頁面

在 clone 下的代碼中,排除掉一些 c#、node.js 使用到的項目性文件,可以看到整個項目中的文件按照功能可以分為三大塊,其中最核心的則是在 SwaggerUIMiddleware 類中,因此,這里主要聚焦在這個中間件類的實現(xiàn)

怎么在asp.net core的中間件中返回具體的頁面

在一個 asp.net core 中間件中,核心的處理邏輯是在 Invoke/InvokeAsync 方法中,結合我們使用 swagger 時的場景,可以看到,在將組件中所包含的頁面呈現(xiàn)給用戶時,主要存在如下兩個處理邏輯

1、當匹配到用戶訪問的是 /swagger 時,返回 301 的 http 狀態(tài)碼,瀏覽器重定向到 /swagger/index.html,從而再次觸發(fā)該中間件的執(zhí)行

2、當匹配到請求的地址為 /swagger/index.html 時,將嵌入到程序集中的文件通過 stream 流的形式獲取到,轉換成字符串,再指定請求的響應的類型為 text/html,從而實現(xiàn)將頁面返回給用戶

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public async Task Invoke(HttpContext httpContext)
{
   var httpMethod = httpContext.Request.Method;
   var path = httpContext.Request.Path.Value;

   // If the RoutePrefix is requested (with or without trailing slash), redirect to index URL
   if (httpMethod == "GET" && Regex.IsMatch(path, $"^/?{Regex.Escape(_options.RoutePrefix)}/?$"))
   {
       // Use relative redirect to support proxy environments
       var relativeRedirectPath = path.EndsWith("/")
           ? "index.html"
           : $"{path.Split('/').Last()}/index.html";

       RespondWithRedirect(httpContext.Response, relativeRedirectPath);
       return;
   }

   if (httpMethod == "GET" && Regex.IsMatch(path, $"^/{Regex.Escape(_options.RoutePrefix)}/?index.html$"))
   {
       await RespondWithIndexHtml(httpContext.Response);
       return;
   }

   await _staticFileMiddleware.Invoke(httpContext);
}

這里需要注意,因為類似于這種功能,我們可能會打包成獨立的 nuget 包,然后通過 nuget 進行引用,所以為了能夠正確獲取到頁面及其使用到的靜態(tài)資源文件,我們需要將這些靜態(tài)文件的屬性修改成嵌入的資源,從而在打包時可以包含在程序集中

對于網(wǎng)頁來說,在引用這些靜態(tài)資源文件時存在一種相對的路徑關系,因此,這里在中間件的構造函數(shù)中,我們需要將頁面需要使用到的靜態(tài)文件,通過構建 StaticFileMiddleware 中間件,將文件映射與網(wǎng)頁相同的 /swagger 路徑下面,從而確保頁面所需的資源可以正確加載

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class SwaggerUIMiddleware
{
   private const string EmbeddedFileNamespace = "Swashbuckle.AspNetCore.SwaggerUI.node_modules.swagger_ui_dist";

   private readonly SwaggerUIOptions _options;
   private readonly StaticFileMiddleware _staticFileMiddleware;

   public SwaggerUIMiddleware(
       RequestDelegate next,
       IHostingEnvironment hostingEnv,
       ILoggerFactory loggerFactory,
       SwaggerUIOptions options)
   {
       _options = options ?? new SwaggerUIOptions();

       _staticFileMiddleware = CreateStaticFileMiddleware(next, hostingEnv, loggerFactory, options);
   }

   private StaticFileMiddleware CreateStaticFileMiddleware(
       RequestDelegate next,
       IHostingEnvironment hostingEnv,
       ILoggerFactory loggerFactory,
       SwaggerUIOptions options)
   {
       var staticFileOptions = new StaticFileOptions
       {
           RequestPath = string.IsNullOrEmpty(options.RoutePrefix) ? string.Empty : $"/{options.RoutePrefix}",
           FileProvider = new EmbeddedFileProvider(typeof(SwaggerUIMiddleware).GetTypeInfo().Assembly, EmbeddedFileNamespace),
       };

       return new StaticFileMiddleware(next, hostingEnv, Options.Create(staticFileOptions), loggerFactory);
   }
}

怎么在asp.net core的中間件中返回具體的頁面

當完成了頁面的呈現(xiàn)后,因為一般我們會創(chuàng)建一個單獨的類庫來實現(xiàn)這些功能,在頁面中,可能會包含前后端的數(shù)據(jù)交互,由于我們在宿主的 API 項目中已經(jīng)完成了對于路由規(guī)則的設定,所以這里只需要在類庫中通過 nuget 引用 Microsoft.AspNetCore.Mvc.Core ,然后與 Web API 一樣的定義 controller,確保這個中間件在宿主程序的調用位于路由匹配規(guī)則之后即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   if (env.IsDevelopment())
   {
       app.UseDeveloperExceptionPage();
   }

   app.UseHttpsRedirection();

   app.UseRouting();

   app.UseAuthorization();

// Endpoint 路由規(guī)則設定
   app.UseEndpoints(endpoints =>
   {
       endpoints.MapControllers();
   });

   // 自定義中間件
   app.UseMiddleware<SampleUIMiddleware>();
}

感謝各位的閱讀,以上就是“怎么在asp.net core的中間件中返回具體的頁面”的內容了,經(jīng)過本文的學習后,相信大家對怎么在asp.net core的中間件中返回具體的頁面這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI