<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET 云原生架構(gòu)師訓(xùn)練營(模塊二 基礎(chǔ)鞏固 路由與終結(jié)點(diǎn))--學(xué)習(xí)筆記

          共 6088字,需瀏覽 13分鐘

           ·

          2020-12-23 22:10

          2.3.3 Web API -- 路由與終結(jié)點(diǎn)

          • 路由模板

          • 約定路由

          • 特性路由

          • 路由沖突

          • 終結(jié)點(diǎn)

          ASP.NET Core 中的路由:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-5.0

          UseRouting 添加路由中間件到管道,路由中間件用來匹配 url 和具體的 endpoint,然后執(zhí)行 endpoint

          UseEndpoints 添加或者注冊 endpoint 到程序中,使得路由中間件可以發(fā)現(xiàn)它們

          • MapRazorPages for Razor Pages 添加所有 Razor Pages 終結(jié)點(diǎn)

          • MapControllers for controllers 添加所有 controller 終結(jié)點(diǎn)

          • MapHub

             for SignalR 添加 SignalR 終結(jié)點(diǎn)
          • MapGrpcService

             for gRPC 添加 gRPC 終結(jié)點(diǎn)

          路由模板

          路由模板由 token 和其他特定字符組成。比如“/”,特定字符進(jìn)行路由匹配的時(shí)候必須全部匹配

          /hello/{name:alpha}

          {name:alpha} 是一段 token,一段 token 包括一個(gè)參數(shù)名,可以跟著一個(gè)約束(alpha)或者一個(gè)默認(rèn)值(mingson),比如 {name=mingson} ,或者直接 {name}

          app.UseEndpoints(endpoints =>
          {
          //endpoints.MapControllers();
          endpoints.MapGet("/hello/{name:alpha}", async context =>
          {
          var name = context.Request.RouteValues["name"];
          await context.Response.WriteAsync($"Hello {name}!");
          });
          });

          路由模板中的參數(shù)被存儲在 HttpRequest.RouteValues 中

          大小寫不敏感

          url 中如果有符合,在模板中用{}代替

          catch-all 路由模板

          • 在 token 前用 * 或者 ** 加在參數(shù)名前,比如 blog/{*slug}

          • blog/ 后面的字符串會(huì)當(dāng)成 slug 的路由參數(shù)值,包括 "/",比如瀏覽器輸入 blog/my/path 會(huì)匹配成 foo/my%2Fpath,如果想要得到 blog/my/path 則使用兩個(gè) ,foo/{path}

          • 字符串.也是可選的,比如 files/{filename}.{ext?},如果要輸入 /files/myFile 也能匹配到這個(gè)路由

          //app.Run(async context =>
          //{
          // await context.Response.WriteAsync("my middleware 2");
          //});

          app.UseEndpoints(endpoints =>
          {
          //endpoints.MapControllers();

          // 將終結(jié)點(diǎn)綁定到路由上
          endpoints.MapGet("/hello", async context =>
          {
          await context.Response.WriteAsync("Hello World!");
          });
          });

          啟動(dòng)程序,訪問:https://localhost:5001/hello

          輸出如下:

          my middleware 1Hello World!

          獲取路由模板參數(shù)

          endpoints.MapGet("/blog/{*title}", async context =>
          {
          var title = context.Request.RouteValues["title"];
          await context.Response.WriteAsync($"blog title: {title}");
          });

          啟動(dòng)程序,訪問:https://localhost:5001/blog/my-title

          輸出如下:

          my middleware 1blog title: my-title

          constraint 約束

          [Route("users/{id:int:min(1)}")]
          public User GetUserById(int id) { }
          app.UseEndpoints(endpoints =>
          {
          endpoints.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
          context =>
          {
          return context.Response.WriteAsync("inline-constraint match");
          });
          });

          約定路由

          默認(rèn)

          endpoints.MapDefaultControllerRoute();

          自定義

          endpoints.MapControllerRoute("default","{controller=Home}/{action=Index}/{id?}");
          // 約定路由
          app.UseEndpoints(endpoints =>
          {
          endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller=Home}/{action=Index}/{id?}");
          });

          // 約定路由也可以同時(shí)定義多個(gè)
          app.UseEndpoints(endpoints =>
          {
          endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller=Home}/{action=Index}/{id?}");

          endpoints.MapControllerRoute(
          name: "blog",
          pattern: "blog/{*article}",
          defaults: new {controller = "blog", action = "Article"});
          });

          特性路由

          controller

          [Route("[controller]")]

          http method

          [HttpGet("option")]

          [HttpGet]
          [Route("option")]

          [HttpGet]
          [Route("option/{id:int}")]

          路由沖突

          [HttpGet]
          //[Route("option")]
          public IActionResult GetOption()
          {
          return Ok(_myOption);
          }

          如果路由相同,啟動(dòng)程序會(huì)報(bào)錯(cuò):

          AmbiguousMatchException: The request matched multiple endpoints. Matches:
          HelloApi.Controllers.ConfigController.GetOption (HelloApi)
          HelloApi.Controllers.ConfigController.GetConfigurations (HelloApi)

          終結(jié)點(diǎn)

          ASP.NET Core 終結(jié)點(diǎn)是:

          • 可執(zhí)行:具有 RequestDelegate。

          • 可擴(kuò)展:具有元數(shù)據(jù)集合。

          • Selectable:可選擇性包含路由信息。

          • 可枚舉:可通過從 DI 中檢索 EndpointDataSource 來列出終結(jié)點(diǎn)集合。

          終結(jié)點(diǎn)可以:

          • 通過匹配 URL 和 HTTP 方法來選擇。

          • 通過運(yùn)行委托來執(zhí)行。

          中間件的每一步都在匹配終結(jié)點(diǎn),所以路由和終結(jié)點(diǎn)之間的中間件可以拿到終結(jié)點(diǎn)的信息

          app.UseRouting();

          // 路由和終結(jié)點(diǎn)之間的中間件可以拿到終結(jié)點(diǎn)的信息
          app.Use(next => context =>
          {
          // 獲取當(dāng)前已經(jīng)被選擇的終結(jié)點(diǎn)
          var endpoint = context.GetEndpoint();
          if (endpoint is null)
          {
          return Task.CompletedTask;
          }
          // 輸出終結(jié)點(diǎn)的名稱
          Console.WriteLine($"Endpoint: {endpoint.DisplayName}");
          // 打印終結(jié)點(diǎn)匹配的路由
          if (endpoint is RouteEndpoint routeEndpoint)
          {
          Console.WriteLine("Endpoint has route pattern: " +
          routeEndpoint.RoutePattern.RawText);
          }
          // 打印終結(jié)點(diǎn)的元數(shù)據(jù)
          foreach (var metadata in endpoint.Metadata)
          {
          Console.WriteLine($"Endpoint has metadata: {metadata}");
          }

          return Task.CompletedTask;
          });

          app.UseEndpoints(endpoints =>
          {
          //endpoints.MapControllers();

          // 將終結(jié)點(diǎn)綁定到路由上
          endpoints.MapGet("/blog/{title}", async context =>
          {
          var title = context.Request.RouteValues["title"];
          await context.Response.WriteAsync($"blog title: {title}");
          });
          });

          啟動(dòng)程序,訪問:https://localhost:5001/blog/my-first-blog

          控制臺輸出如下:

          Endpoint: /blog/{title} HTTP: GET
          Endpoint has route pattern: /blog/{title}
          Endpoint has metadata: System.Runtime.CompilerServices.AsyncStateMachineAttribute
          Endpoint has metadata: System.Diagnostics.DebuggerStepThroughAttribute
          Endpoint has metadata: Microsoft.AspNetCore.Routing.HttpMethodMetadata

          打印 http 方法

          // 打印終結(jié)點(diǎn)的元數(shù)據(jù)
          foreach (var metadata in endpoint.Metadata)
          {
          Console.WriteLine($"Endpoint has metadata: {metadata}");
          // 打印 http 方法
          if (metadata is HttpMethodMetadata httpMethodMetadata)
          {
          Console.WriteLine($"Current Http Method: {httpMethodMetadata.HttpMethods.FirstOrDefault()}");
          }
          }

          啟動(dòng)程序,訪問:https://localhost:5001/blog/my-first-blog

          控制臺輸出如下:

          Current Http Method: GET

          修改終結(jié)點(diǎn)名稱、元數(shù)據(jù)

          app.UseEndpoints(endpoints =>
          {
          //endpoints.MapControllers();

          // 將終結(jié)點(diǎn)綁定到路由上
          endpoints.MapGet("/blog/{title}", async context =>
          {
          var title = context.Request.RouteValues["title"];
          await context.Response.WriteAsync($"blog title: {title}");
          }).WithDisplayName("Blog")// 修改名稱
          .WithMetadata("10001");// 修改元數(shù)據(jù)
          });
          • 調(diào)用 UseRouting 之前,終結(jié)點(diǎn)始終為 null。

          • 如果找到匹配項(xiàng),則 UseRouting 和 UseEndpoints 之間的終結(jié)點(diǎn)為非 null。

          • 如果找到匹配項(xiàng),則 UseEndpoints 中間件即為終端。稍后會(huì)在本文檔中定義終端中間件。

          • 僅當(dāng)找不到匹配項(xiàng)時(shí)才執(zhí)行 UseEndpoints 后的中間件。

          GitHub源碼鏈接:

          https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/HelloApi

          課程鏈接

          .NET云原生架構(gòu)師訓(xùn)練營講什么,怎么講,講多久


          歡迎各位讀者加入微信群一起學(xué)習(xí)交流,
          在公眾號后臺回復(fù)“加群”即可~~


          瀏覽 66
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  7777精品视频 | 国产污视频在线 | 日韩三级片网站在线观看 | 国产黄色A级毛片 | 青青亚洲自拍 |