iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
自我挑戰組

.NET Core WebApi網頁應用開發系列 第 9

.Net Core Web Api_筆記09_web api的屬性路由模板兩種寫法_路由模板使用

在.net core mvc跟.net core web api專案中預設各自採用的一些配置
有不太一樣的地方,在Startup.cs中

.net core (.net5) mvc專案

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyMVCTest0
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

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

https://ithelp.ithome.com.tw/upload/images/20210911/20107452b9ZJLY6YOr.png

.net core (.net5) web api專案

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyApiTest0
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

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

https://ithelp.ithome.com.tw/upload/images/20210911/20107452dggsZkoztg.png

在.net core api專案除了在ConfigureServices()服務注入中別於Mvc只有注入Controllers()而已
預設還會自動被配置為採用「屬性路由」也就是MapControllers(),表示去對應控制器的屬性路由,別於MVC的傳統路由(Conventional routing)配置。

屬性路由從[Route("")]當中進行設定
比方如下訪問的路由就是
api/student

https://ithelp.ithome.com.tw/upload/images/20210911/20107452g0360a8QWK.png

而在action下也可進行相應的屬性路由配置
比方要訪問Show()則路由就是
api/student/display

https://ithelp.ithome.com.tw/upload/images/20210911/201074527IIyCxS8S8.png

而也可將屬性路由去跟HTTP verb attributes(動作名詞、HTTP動作動詞)去結合
產生Route template for action 第二種縮減的寫法

https://ithelp.ithome.com.tw/upload/images/20210911/20107452Uff1yV83GN.png

路由模板(Route Template):從Client端輸入的URL如何匹配到Server端對應Action的路由
再白話一點說就是怎麼給Client端指定對應的Response跟Response之前的業務邏輯處理。

無論是MVC的傳統路由或目前探討的Web API屬性路由
都涉及到要去配置Route Template的議題

於Route Template中分兩種占位符(標記取代)
1.中方括號[] , 又固定只包含三種關鍵字[控制器]、[動作]、[區域]
[controller] , [action] , [area]

2.大花括號{} ,代表路由傳入的參數值

以下面為例就是透過傳入{id}過濾將對應person資料呈現

https://ithelp.ithome.com.tw/upload/images/20210911/20107452VWIgYW2L5l.png

而我們也可透過[action]的標記取代
來直接透過action method 名稱來做訪問

https://ithelp.ithome.com.tw/upload/images/20210911/20107452XlyaU6elTS.png

路由屬性(RouteAttribute)

在 web api專案中可讓我們不論在Controller層級或Action層級都能使用Route 屬性
以下是微軟對其封裝的程式

#region 組件 Microsoft.AspNetCore.Mvc.Core, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\5.0.0\ref\net5.0\Microsoft.AspNetCore.Mvc.Core.dll
#endregion

using Microsoft.AspNetCore.Mvc.Routing;
using System;

namespace Microsoft.AspNetCore.Mvc
{
    //
    // 摘要:
    //     Specifies an attribute route on a controller.
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class RouteAttribute : Attribute, IRouteTemplateProvider
    {
        //
        // 摘要:
        //     Creates a new Microsoft.AspNetCore.Mvc.RouteAttribute with the given route template.
        //
        // 參數:
        //   template:
        //     The route template. May not be null.
        public RouteAttribute(string template);

        public string Template { get; }
        //
        // 摘要:
        //     Gets the route order. The order determines the order of route execution. Routes
        //     with a lower order value are tried first. If an action defines a route by providing
        //     an Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider with a non null order,
        //     that order is used instead of this value. If neither the action nor the controller
        //     defines an order, a default value of 0 is used.
        public int Order { get; set; }
        public string Name { get; set; }
    }
}

在屬性上面定義的RouteAttribute
可讓我們除了一般route template之外
還能夠去設置Name屬性、Order屬性(在HttpMethod屬性或Route屬性都能設置)

Name屬性
HttpMethodAttribute.Name Property

RouteAttribute.Name Property

Gets the route name. The route name can be used to generate a link using a specific route, instead of relying on selection of a route based on the given set of route values.

有點類似替路由模板設置別名的感覺
https://ithelp.ithome.com.tw/upload/images/20210911/20107452vkvzMExvD6.png

可幫助我們去透過自訂的路由名稱來產生對應匹配的路由網址
換言之,藉由名稱就能夠得到路由模板。

以前幾篇範例Student來改

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using MyApiTest1.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyApiTest1.Controllers
{
    [Route("api/[controller]", Name = "StuApi")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        public LinkGenerator LinkGenerator { get; set; }

        public StudentController(LinkGenerator LinkGenerator)
        {
            this.LinkGenerator = LinkGenerator;
        }

        [HttpGet("/Student/GetUrl")]
        public string BuildUrl()
        {
            string url = LinkGenerator.GetPathByRouteValues("G_ID", new { id = 3 });
            return url;
        }

        [HttpGet("GetPersonById/{id}", Name = "G_ID")]
        public ActionResult<Person> GetPerson(int id)
        {
            List<Person> lsPersons = new List<Person>()
            {
                new Person(){Id=1,Name="Amy",Age=22,Sex="woman"},
                new Person(){Id=2,Name="Jessica",Age=25,Sex="woman"},
                new Person(){Id=3,Name="Banson",Age=24,Sex="man"}
            };
            return lsPersons.Where(item => item.Id == id).FirstOrDefault();
        }
    }
}

這裡我們可以透過LinkGenerator 注入到建構子後
整個Controller的任一action中都能夠去使用它
來去透過Name屬性生成路由模板

測試效果即可看到
預設透過 路由模板/student/geturl
幫我們產生了一個新的路由模板去對person做資料過濾請求
https://ithelp.ithome.com.tw/upload/images/20210911/20107452JE0HjhQ4ky.png

Order屬性
HttpMethodAttribute.Order Property

RouteAttribute.Order Property

Gets the route order. The order determines the order of route execution. Routes with a lower order value are tried first. If an action defines a route by providing an IRouteTemplateProvider with a non null order, that order is used instead of this value. If neither the action nor the controller defines an order, a default value of 0 is used.

則是讓我們能夠去設置路由順序,預設當Order為Null時順序為0。
數字愈小的優先權愈高

本篇同步發表至個人部落格
https://coolmandiary.blogspot.com/2021/09/net-core-web-api09web-api.html

Ref:

Convention Routing VS Attribute Routing
https://www.c-sharpcorner.com/article/convention-routing-vs-attribute-routing/

Routing to controller actions in ASP.NET Core
https://docs.microsoft.com/en-gb/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0#ordering-attribute-routes

ASP.NET Core 中的路由至控制器動作
https://docs.microsoft.com/zh-tw/aspnet/core/mvc/controllers/routing?view=aspnetcore-5.0#token-replacement-in-route-templates-controller-action-area

Web API Routing
https://www.tutorialsteacher.com/webapi/web-api-routing

Everything You Should Know About ASP .NET Core Routing
https://thecodeblogger.com/2021/05/28/everything-you-should-know-about-asp-net-core-routing/

Conventional vs Attribute Routing In ASP .NET Core Apps
https://thecodeblogger.com/2021/05/29/conventional-vs-attribute-routing-in-asp-net-core-apps/

Attribute Routing in ASP.NET Core
https://dotnetthoughts.net/attribute-routing-in-aspnet-core/

Understanding Routing Precedence In ASP.NET MVC And Web API
https://www.codeproject.com/Articles/1110613/Understanding-Routing-Precedence-in-ASP-NET-MVC-an
https://www.c-sharpcorner.com/article/understanding-routing-precedence-in-asp-net-mvc-and-web-api/

ASP.NET MVC Controller Attribute Route Precedence
https://www.softwareblogs.com/Posts/Details/18/aspnet-mvc-controller-attribute-route-precedence

Route Names and Route Orders in Attribute Routing
https://dotnettutorials.net/lesson/route-names-and-route-orders-attribute-routing/

What's the use of the Name parameter in RouteAttribute?
https://stackoverflow.com/questions/54412718/whats-the-use-of-the-name-parameter-in-routeattribute

ASP.NET WebApi 路由配置
https://www.cnblogs.com/Jeely/p/10956207.html

ASP. NET Web Api 2 學習筆記
http://blog.appx.tw/2018/06/01/asp-net-web-api-2-%E5%AD%B8%E7%BF%92%E7%AD%86%E8%A8%98/


上一篇
.Net Core Web Api_筆記08_HTTP資源操作模式PATCH
下一篇
.Net Core Web Api_筆記10_路由約束
系列文
.NET Core WebApi網頁應用開發16

尚未有邦友留言

立即登入留言