تعلم Attribute Routing في ASP.NET Core

-

في الدروس السابقة تعلمنا ما يسمى  Convention Routing. يوجد أسلوب ثاني لعمل routing يُعرف باسم Attribute Routing. في Attribute Routing، يتم تطبيق route ك attributes  #C  مباشرة إلى controller and actions.

تمام نطبق مثال بسيط حتي نفهم الفكره، طبق الكود التالي في Home Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace URLRouting.Controllers
{
    public class HomeController : Controller
    {
        [Route("CallRoute")]
        public IActionResult Index()
        {
            return View();
        }
        // other actions
    }
}
في الكود السابق طبقنا attribute  باسم  [Route("CallRoute")] على Index Action .
الان المطلوب نحذف Route الموجود في Startup.cs class باستثناء المسار الافتراضي (يعني يكون يحتوي فقط على):

app.UseEndpoints(endpoints =>
            {  
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
الآن قم بتشغيل التطبيق الخاص بك وانتقل إلى
https://localhost:44382/CallRoute
اكيد بتكون النتيجة انه تم استدعاء Index action   في Home controller .
واذا حاولت تدخل الى الروابط URL التالية ل Index action  
https://localhost:58470/Home/Index
https://localhost:58470  
اكيد بتكون النتيجة ان هذه الروابط لم تعد تعمل والسبب في ذلك ان المسارات غير متطابقة Convention Routing.
ستكون نتيجة التنفيذ: 



لاحظ ان action routes الأخرى من Convention routing مثل
https://localhost:44382/students/allstudent 
بتستمر في العمل دون مشاكل. وهذا يعني :
إذا كان هناك Attribute Routing  مطبق على Action في Controller ، فلن تعمل Convention Routes  ل Controller or Action .

استخدام ‘controller’ & ‘action’  في Attribute Routing

واضح من الاسماء ان استخدام المصطلحين [controller] [action]  يشير إلى اسمي Controller and Action ، تمامًا كما هو الحال في Convention Routing.
لفهمها، قم بإنشاء Controller وقم بتسميتها AdminController.cs. وبعدها أضف الكود التالي اليها:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Controllers
{
    public class AdminController : Controller
    {
        [Route("[controller]/DashBoard")]
        public string Index()
        {
            return "Admin Controller, Index View";
        }
        public string List()
        {
            return "Admin Controller, List View";
        }
    }
}

تمام خلونا نفهم شو عملنا.يمكنك
طبقنا Attribute Route على Index action.ولاحظ ان اضنفا في هذا المسار مصطلح باسم controller والي بيعني ان عند استدعاء عنوان URL لهذا Controller فا اجباري يحتوي هذا URL علىsegment باسم Controller وبعدو DashBoard.
لذلك لاستدعاء index، لازم يكون URL 
https://localhost:44382/Admin/DashBoard
في action المسمى List لاحظ أنه ما طبقنا Attribute Routes، لذلك يمكن استدعاء هذا action باستخدام Convention Routing ، وبكون URL
  https://localhost:58470/Admin/List
تمام خلونا نطبق مثال ثاني حتى نفهم الفكره:
أضف action أخرى باسم Show  إلى ملف AdminController.cs مع attribute routing كما هو موضح في الكود :
[Route("[controller]/DashBoard/[action]")]
        public string Show()
        {
            return "Admin Controller, Show View";
        }
انتقل الى الرابط التالي: 
https://localhost:44382/Admin/DashBoard/Show
يمكن أيضًا تطبيق attribute routing على Controller بشكل كامل. سيؤدي هذا إلى جعل كل action method  في هذا Controller   ترث  attribute route.
لنقم بتغير code في  Admin Controller  كما هو موضح أدناه:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Controllers
{
    [Route("Student/[controller]/DashBoard/[action]/{id?}")]
    public class AdminController : Controller
    {
      // [Route("[controller]/DashBoard")]
        public string Index()
        {
            return "@@#Admin@@# Controller, @@#Index@@# View";
        }
        public string List()
        {
            return "@@#Admin@@# Controller, @@#List@@# View";
        }
        [Route("[controller]/DashBoard/[action]")]
        public string Show()
        {
            return "@@#Admin@@# Controller, @@#Show@@# View";
        }
    }
}
يتم تطبيق Attribute Routing  على Admin controller بحيث  جميع action method  ترث Attribute Routing .

امثلة على عناوين URL لاستدعاء Index action:

/Student/admin/DashBoard/Index
/Student/admin/DashBoard/Index/100
/Student/admin/DashBoard/Index/hello

امثلة على عناوين URL لاستدعاء List action:

/Student/admin/DashBoard/List
/Student/admin/DashBoard/List/100
/Student/admin/DashBoard/List/Hello
تطبيق القيود على Attribute Routing

يمكن تطبيق Route Constraint  على Attribute Routing.
في المثال السابق حيث قمنا بإنشاء Custom Constraint يسمى CityConstraint. ويمكن تطبيقه ايضا على attribute routing، تمامًا كما فعلنا سابقا وحتى نفهم كيف الطريقة طبق الكود التالي:

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Controllers
{
    [Route("Student/[controller]/DashBoard/[action]/{id:allowCity?}")]
    public class AdminController : Controller
    {
      // [Route("[controller]/DashBoard")]
        public string Index()
        {
            return "@@#Admin@@# Controller, @@#Index@@# View";
        }
        public string List()
        {
            return "@@#Admin@@# Controller, @@#List@@# View";
        }
        [Route("[controller]/DashBoard/[action]")]
        public string Show()
        {
            return "@@#Admin@@# Controller, @@#Show@@# View";
        }
    }
}
تمام نشغل التطبيق بالانتقال الى الرابط :
https://localhost:44382/Student/admin/DashBoard/Index/Irbid