在.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?}");
            });
        }
    }
}

.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();
            });
        }
    }
}

在.net core api專案除了在ConfigureServices()服務注入中別於Mvc只有注入Controllers()而已
預設還會自動被配置為採用「屬性路由」也就是MapControllers(),表示去對應控制器的屬性路由,別於MVC的傳統路由(Conventional routing)配置。
屬性路由從[Route("")]當中進行設定
比方如下訪問的路由就是
api/student

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

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

路由模板(Route Template):從Client端輸入的URL如何匹配到Server端對應Action的路由
再白話一點說就是怎麼給Client端指定對應的Response跟Response之前的業務邏輯處理。
無論是MVC的傳統路由或目前探討的Web API屬性路由
都涉及到要去配置Route Template的議題
於Route Template中分兩種占位符(標記取代)
1.中方括號[] , 又固定只包含三種關鍵字[控制器]、[動作]、[區域]
[controller] , [action] , [area]
2.大花括號{} ,代表路由傳入的參數值
以下面為例就是透過傳入{id}過濾將對應person資料呈現

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

路由屬性(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
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.
有點類似替路由模板設置別名的感覺
可幫助我們去透過自訂的路由名稱來產生對應匹配的路由網址
換言之,藉由名稱就能夠得到路由模板。
以前幾篇範例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做資料過濾請求
Order屬性
HttpMethodAttribute.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/