ASP.NET Core Convention-Based URL Routing

-

يتم استخدام ASP.NET Core URL Routing لإنشاء URL patterns  للتطبيق الخاص بك. حيث يعمل على مطابقة طلبات HTTP الواردة ويرسل تلكالطلبات إلى application’s endpointss. و Endpoints هي تلك الوحدات المسؤولة عن معالجة الطلب. يتم تحديد هذه الطلبات داخل Configure() method في Startup.cs class.

يحتوي Routing System على وظيفتين رئيسيتين:

  • تعيين عناوين incoming URLs إلى Controllers and Actions.
  • يقوم بإنشاء عناوين outgoing URLs  بحيث يتم استدعاء specific action method عندما ينقر المستخدم فوق link.

هناك طريقتان لإنشاء routes في  ASP.NET Core:

  • Convention-Based Routing (ما سيتم تناوله في هذا الدرس)
  • Attribute-Based Routing
تمام نبدأ الدرس بالتأكد من اعدادات التطبيق :
في مشروعنا StudentsAcademy، افتح Startup.cs class تأكد من ان الكود التالي موجود بداخله:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace StudentsAcademy
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        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");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                // Default route
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
وعملنا في الدروس السابقة Controller  باسم HomeController داخل Controllers folder وأضفنا action باسم Index  إليها:
الكود:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using StudentsAcademy.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using StudentsAcademy.Services;
using StudentsAcademy.Share;
namespace StudentsAcademy.Controllers
{
    public class HomeController : Controller
    { 
public IActionResult Index()
        {
            return View();
        }
    }
}

أضفنا أيضًا view باسم Index داخل Views ➤ Home Folder. 

غير الكود في View الى:

@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <title>Routing</title>
</head>
<body>
    <h1>Home Controller, Index View</h1>
</body>
</html>
الآن خلونا نشغل التطبيق بالنقر فوق الرابط 
https://localhost:44382/
سترى محتويات Index View معروضة بواسطة المتصفح. انظر الصورة أدناه:


تمام خلونا نبدا بشرح الأجزاء الموجودة segments في URLs قبل البدء بشرح كيفية عمل URL Routing.

ما هي Segment  في URL

Segmentsهي أجزاء من عنوان URL ، باستثناء hostname و query string ، ويتم الفصل بينها بالرمز "/".

توضح الصورة المقدمة ما هي الأجزاء:



يمكن أن يحتوي عنوان URL على 0 جزء أو أجزاء لا نهائية ولكن معظم التطبيقات لا تحتاج إلى أكثر من 3 أجزاء.

عندما يكون هناك طلب HTTP، فإن مهمة نظام التوجيه Routing System  هي فحص عنوان URL واستخراج segments values منه.

يتم تحديد المسار الافتراضي في ()Configure الموجوده في  Startup.cs class، ويعمل Net Core. تعريف افتراضي للمسار حيث تم تحديد المسار الافتراضي default route  ("default" هو مجرد اسم ويمكن أن يكون أي اسم ثاني). 

داخل هذه method استخدمنا UseEndpoints الذي يستخدم لإنشاء مسار واحد a single route، وعملنا اضافة  Endpoints ل Controller’s action. لهذا استخدمنا ()MapControllerRoute . 

يُطلق على المسار الفردي اسم default route.

الكود:

app.UseEndpoints(endpoints =>
            {
                // Default route
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
في الاصدارات السابقة من ASP.NET Core مثل 2.0 و 2.1 و 2.2. كنا نستخدم طريقة ()app.UseMvc التي تشبه إلى حد كبير ()app.UseEndpoints كما في الكود اسفل:
app.UseMvc(routes =>
{
   routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
يقدم 5.0 ASP.NET Core مفهوم Endpoint Routing لذا لا يُنصح باستخدام طريقة ()app.UseMvc  بعد الآن.

يتم تمثيل segment داخل الأقواس {…}. يتكون المسار الافتراضي default route من 3 segments مفصولة بالرمز / وهي:
  • {controller=Home} تشير الى اسم controller الافتراضي.
  • {action=Index} يشير الى Action الافتراضي.
  • {id?} يشير الى Parameter ، الإشارة ?  تعني ان هذا Parameter اختياري.

هذه segments  تعتبر default value  اختيارية. حيث تعمل على توجيه واخبار routing system بأخذ قيمة افتراضية معينة إذا كان segment غير موجود في عنوان URL.
عند تشغيل التطبيق الحالي، ستلاحظ أنه تم استدعاء Index View  ل Home Controller بالرغم من عدم كتابة ذلك بشكل صريح في العنوان.
لاحظ العنوان
https://localhost:44382/
حيث لا يوجد أي segments. ومع ذلك تم تشغيل الرابط 
https://localhost:44382/Home/Index
 السبب هو default values ل segments، وهي:
  • ‘Home’ for the controller
  • ‘Index’ for action.
يوجد أدناه الجدول الذي سيعرض جميع عناوين URL المطابقة المحتملة التي تم إجراؤها بواسطة المسار الحالي:

Maps to
URL
Segments
controller = Home action = Index
/
0
controller = Home action = Index
/Home
1
controller = About action = Index
/About
1
controller = Home action = Index
/Home/Index
2
controller = Home action = List
/Home/List
2
controller = About action = Show
/About/Show
2
controller = About action = Index
/Home/Index/3
3
No match
/Home/List/3
3
واضح الان ان المسار الحالي سيتطابق مع ما يصل إلى 3 segments  في عنوان URL. في حال وجود اكثر من 3 segments سوف يفشل وستظهر رسالة خطأ 404.
تمام الان خلونا نعمل إزالة default values لكل من Controller and View في route كما هو موضح:
app.UseEndpoints(endpoints =>
{
    // Default route
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller}/{action}");
});
تمام الان دور نجرب تشغيل التطبيق. ستلاحظ رسالة خطأ HTTP 404 لأن نظام التوجيه لا يمكنه تعيين عنوان URL لأي controller. كما هو واضح في الصورة في الاسفل:



طيب خلونا نحاول نجرب العنوان
URL - https://localhost:44382/Home/Index
ولاحظ هون ان تم استدعاء Index method من Home Controller’s.
اكيد بتلاحظ ان هذا route يتطابف تمامًا مع 2 segments في عنوان URL. واذا كان عدد المقاطع يتكون من 0 ، 1 ، 3 ، 4 ، او اكثر اكيد بتفشل وتعطي رسالة خطأ 404.
يعرض الجدول التالي جميع عناوين URL المطابقة المحتملة التي يوفرها هذا المسار:


Maps to
URL
Segments
No match
/
0
No match
/Home
1
controller = Home action = Index
/Home/Index
2
controller = Home action = List
/Home/List
2
controller = About action = List
/About/List
2
No match
/Home/Show/4
3
التوجيه القائم على Convention

شو هو Convention:  
في ASP.NET Core، يتم تطبيق Convention-Based Routing داخل ()Configure  في  Startup class. وحتى نعمل ذلك بنستخدام طريقة ()app.UseEndpoints  واكيد شفنا كيف في الاقسام السابقة. وفيما يلي بنحكي عن جوانب هذا النوع من التوجيه.
النصوص الثابتة   static texts 
يدعم URL Routing النصوص الثابتة   static texts في routes.
نبدأ بحذف المسار الافتراضيdefault route  وبعدها نضيف مسار يحتوي على نص شوف الكود في الاسفل:
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "news1",
        pattern: "News/{controller=Home}/{action=Index}");
});
اكيد لاحظت ان المسار يحتوي على static text – باسم  News 
الكود: 
pattern: "News/{controller=Home}/{action=Index}");
جرب شغل التطبيق وانتقل إلى
URL - https://localhost:44382/News.
والنتيجة بتكون تم استدعاء Index action الخاص ب Home Controller’s.
طيب نفهم شو صار.
حسب الكود الخاص بالمسار،سيتطابق المسار مع 3 Segments. ويجب أن يكون الأول News، والثاني والثالث مقاطع اختيارية وهم : controller=Home و action=Index. طيب وفي حال ما كانت موجوده،الجواب: سيتم استخدام القيم الافتراضية وهي Home for Controller and Index for Action.
:
يمكن أيضًا دمج نص ثابت مع مقاطع متغيرة (like controllers or actions). قم بتعديل كود المسار كما هو موضح أدناه:
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "news2",
        pattern: "News{controller}/{action}");
});
عملنا هون إضافة كلمة ثابته وهي News ، حيث ستنضم إلى Controller’s segment value. الآن قم بتشغيل التطبيق وانتقل إلى
 URL - https://localhost: 44382/NewsHome/Index.
 ستجد أنه تم استدعاء  Index Action method في Home Controller’s



يمكن أن يساعد استخدام static text  في routes أيضًا في الحفاظ على الروابط القديمة Old URLs. ولنفترض أن عندك controller تسمى Shopping وقمت الآن باستبدالها ب Home Controller. يجب أن تتأكد من أن عناوين URL السابقة
 (eg /Shopping/Clothes, /Shopping/Electronics, /Shopping/Grocery, etc) ويجب تعيينها إلى Home Controller.
لتمثيل هذه الطريقة يجب إضافة route لأداء هذا الشيء كما هو موضح بالاسفل:
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "shop",
        pattern: "Shopping/{action}",
        defaults: new { controller = "Home" });
});

لاحظ ان route يتطابق مع 2 Segments  حيث يكون first segment هو Shopping.
وبعدها يتم أخذ action value من segment الثاني. لا يحتوي URL pattern  على segment ل controller ، لذلك يتم استخدام القيمة الافتراضية. توفر defaults argument قيمة controller value وهي Home controller.
الآن سيتم تعيين ULRs مثل / Shopping / Clothes / و Shopping / Electronics و / Shopping / Grocery إلى Home Controller بدلاً من وحدة Shopping Controller.
للتحقق من ذلك
 افتح العنوان
 URL - https://localhost:44382/Shopping/Index 
 في متصفحك. ستجد أنه تم استدعاء Index method الخاصة ب Home Controller’s. انظر الصورة أدناه:



توفير القيم الافتراضية ل Controller و Action لعنوان URL
إذا كنت تريد تعيين Controller محددة و Action  معين إلى عنوان URL ، فيجب عليك تخصيص القيم الافتراضية لكل من Controller و Action كما هو موضح في الكود التالي:
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "old",
        pattern: "Shopping/Old",
        defaults: new { controller = "Home", action = "Index" });
});
في حال الدخول الى الرابط:
– https://localhost:44382/Shopping/Old.
فسيتم توجيه المستخدم الى Index في Home Controller 



ترتيب Routes 
يمكن تطبيق أكثر من route في التطبيق. لكن تذكر دائمًا، يتم تطبيق المسارات بالترتيب الذي تم تعريفها به. يحاول نظام التوجيه مطابقة عنوان URL الوارد مع المسار المحدد الأول ولا ينتقل إلى المسار التالي الا في حالة عدم وجود تطابق للمسار الأول. لذلك يجب تحديد المسارات حسب الأهمية في التطبيق.
وحتى نفهم الموضوع نطبق الكود التالي:
لنقم بإضافة 2 routes  في ()Configure في Startup
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
    name: "old",
    pattern: "Shopping/Old",
    defaults: new { controller = "Home", action = "Index" });
    endpoints.MapControllerRoute(
    name: "shop",
    pattern: "Shopping/{action}",
    defaults: new { controller = "Home" });
});

ثم أضف Action method جديدة باسم Old   في Home Controller. ثم أضف الكود التالي:
public IActionResult Old ()
{
    return View();
}
الان سنقوم بإضافة View باسم Old في Views ➤ Home 

@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <title>Routing</title>
</head>
<body>
    <h1>Home Controller, Old View</h1>
</body>
</html>

قم بتشغيل التطبيق وانتقل إلى
 URL - https://localhost:44382/Shopping/Old
 ستكون النتيجة استدعاء Index action  من Home Controller  

طيب كبف وليش صار هيك :
السبب لأنه عند طلب العنوان
 URL https://localhost:44382/Shopping/Old
يبدأ نظام التوجيه في مطابقة عنوان URL مع المسارات بالترتيب حسب ما هو معرف في ()Configure. ونظرًا لأن المطابقة تحدث في المسار الأول first route  نفسه ، يتم عرض Index View ل Home Controller في المتصفح.
طيب جرب تغير ترتيب المسارات routes بإحضار المسار الثاني قبل الأول كما هو موضح في الكود أدناه:
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "shop",
        pattern: "Shopping/{action}",
        defaults: new { controller = "Home" });
    endpoints.MapControllerRoute(
        name: "old",
        pattern: "Shopping/Old",
        defaults: new { controller = "Home", action = "Index" });
});
ارجع شغل التطبيق وعمل بتحديث نفس عنوان
https://localhost:44382/Shopping/Old 
واكيد هذه المرة سوف تجد أن Old Index ل Home Controller يتم استدعاءه. انظر الصورة أدناه:

والسبب في ذلك هو أن نظام التوجيه هذه المرة يجد مسارًا مختلفًا مطابقًا لعنوان URL، وهذا المسار هو -
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "shop",
        pattern: "Shopping/{action}",
        defaults: new { controller = "Home" });
});
ملاحظة: تذكر دائمًا ترتيب المسارات حسب الأهمية في التطبيق، وإلا فسيقوم نظام التوجيه بإجراء التعيينات بشكل خاطئ.

تخصيص Segment Variables  
segment variables حكينا عنها سابقا في  routes وهي controller and action . كما تلاحظ انها ثابته ولا يمكن التعديل عليها، لكن يمكن إضافة Custom Segment variables  الخاصة بك في المسارات. سنوضح فيما يلي كيفية القيام بذلك.
تمام خلونا نحذف كل routes القديمة وبعدها نضيف route في ()Configure في ملف Startup.cs:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "MyRoute",
        pattern: "{controller=Home}/{action=Index}/{id}");
});
في هذا المسار، أضفت Custom Segment variables عن طريق اضافة variables باسم Id. بعد ذلك أضف Action method جديدة تسمى Check الى Home Controller:
public IActionResult Check()
{
    ViewBag.ValueofId = RouteData.Values["id"];
    return View();
}
في هاذ action يتم استقبال متغير باسم Id ،  بحيث يتم الحصول على قيمة هذا Id من route URL pattern، هذا Id  هو  custom variable في route URL pattern . وفي Action يتم الحصول على قيمته باستخدام خاصية RouteData.Values، ويخزن هذه القيمة في متغير ViewBag باسم ValueofId.
تمام الآن قم بإنشاء View باسم Check  داخل مجلد Home ➤ Check. ثم أضف الكود في الاسفل الى View. الهدف ظهار قيمة Custom Segment   المسمى Id في متغير ViewBag.

@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <title>Routing</title>
</head>
<body>
    <h1>Home Controller, Check View</h1>
    <h2>Id value is: @ViewBag.ValueofId</h2>
</body>
</html>

قم بتشغيل التطبيق بالانتقال الى الرابط:
https://localhost:44382/Home/Check/cSharp
سيقوم نظام توجيه URL الخاص بـ ASP.NET Core بالمطابقة مع المقطع الثالث third segment وهو cSharp في عنوان URL هذا كقيمة لمتغير "id".
ستكون نتيجة التنفيذ كما في الصورة

طيب في حال ما ارسالنا قيمة إلى الجزء الثالث من عنوان URL ، على سبيل المثال افتح الرابط
 URL - https://localhost:58470/Home/Check
 في هذا المثال لا يجد نظام التوجيه أي مسارات مطابقة ولذا يتم عرض HTTP ERROR 404 في المتصفح.


تخصيص Segment Variable ك Action Method Parameters

إذا قمت بتعريف Parameters في Action Methods  بحيث تكون أسماء parameters مماثلة لأسماء URL parameter variables ، فسيمرر ASP.NET Core MVC framework تلقائيًا القيم التي تم الحصول عليها من متغيرات Parameters في URL إلى parameters في action method.
في نفس المسار من القسم أعلاه. يحتوي على custom segment – باسم Id.

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

تمام وحتي نحصل على قيمة id  التي تم تمريرها إلى عنوان URL ، يمكن إضافة parameter باسم Id  إلى Action Method. لذا قم بتغيير الكود الخاصب ب Check action عن طريق إضافة id parameter إليها كما هو موضح أدناه:

public IActionResult Check(int id)
{
    ViewBag.ValueofId = id;
    return View();
}
وبعدها عملنا عرض قيمة Id داخل action method في متغير من نوع ViewBag باسم ValueofId

إضافة URL Segment اختياري

الجزء الذي لا تحتاج إلى تحديده بشكل اساسي في المسار يسمى optional URL Segment. وعادة تستخدم  علامة استفهام (؟) بعدها لتتعبير عن ذلك(ومعنى ذلك انه اختياري)، وبتكون النتيجة :في حال الارسال سيتم قراءته وفي حال عدم الارسال لن يكون هناك خطأ.
تمام وحتي نفهم الموضوع خلونا نعمل حذف ل جميع routes في التطبيق وبعدها نضيف route واحدًا فقط كما هو موضح أدناه.


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

في هذا route، عملنا id segment اختياريًا بإضافة العلامة "?"

تمام في هذا الكود عندما لا يتم توفير أي قيمة ل optional segment variable، فإن قيمة parameter المقابلة ستكون null.
لاختبار ذلك، خلونا نغيير Check action method في Home Controller  كما هو موضح في الكود أدناه:

public IActionResult Check()
{
    ViewBag.ValueofId = RouteData.Values["id"];
    return View();
}

نجرب نشغل التطبيق وما نرسل Id الى action، واكيد بتلاحظ انه لن يكون هناك أي خطأ وسيتم عرض قيمة Empty Value  
https://localhost:58470/Home/Check
يتم عرض empty value لأن نظام التوجيه لا يجد قيمة Custom Segment Variable هذا المسمى id ، ولذا يتم عرض empty value ل Id في المستعرض
بعد ذلك، قم بتغيير Check action method ل Home Controller  كما هو موضح في الكود أدناه:

public IActionResult Check(string id)
{
    ViewBag.ValueofId = id ?? "Null Value";
    return View();
}

لاحظ ان غيرنا نوع id parameter إلى string. 
الكود 
ViewBag.ValueofId = id ?? "Null Value" 
في هذا الكود بنعمل على التحقق من قيمة "id" اذا كانت Null (ويتم تنفيذها بواسطة ?? operator) ، وبعد هيك سيتم إضافة القيمة  "Null Value" في متغير ViewBag ، وفي حال غير ذلك فسيتم إضافة قيمة Id الى متغير ViewBag.
قم بتشغيل التطبيق الخاص بك وانتقل إلى
 URL - https://localhost:58470/Home/Check.
 سترى Null Value  معروضة في المتصفح

التحكم بطول Routes واستخدام catchall  

كل الي عملناه سابقا كان طرق يمكن أن تتطابق مع عنوان URL لحد 3 segments. طيب وشو لو كان عندنا عنوان URL يحتوي على اكثر من هيك مثلا 4, 5 او اكثر.
للتعامل مع ذلك إحدى الطرق هي إضافة routes جديدة بعدد  segments.
على سبيل المثال لمطابقة عنوان URL المكون من 4 أجزاء –

 http://localhost: 58470/Home/Check/Hello/World 
، يمكنك إضافة مسار جديد موضح أدناه:

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

سيعمل هذا الكود لحد  4 segment ،ولكن في حال إضافة segment  جديد يجب تعديل الكود، لإضافة مسارات جديدة لمطابقة 5 segments وهكذا. تمام الامور واضحه هيك، تخيل يكون في التطبيق مثلا segment 10 ، تخيل كيف بكون الكود واكيد الامر بهذا الشكل بكون متعب ويسبب code duplication. بدلاً من ذلك، يمكنك استخدام المصطلح * catchall في مساراتك لمطابقة العدد المتغير ل segments.
تمام طبق المثال التالي :

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

في هذا الكود أضفنا {* catchall} باعتباره 4th segment  في route. تُستخدم المقاطع الثلاثة الأولى ل controller, action & id variable. إذا كان عنوان URL يحتوي على أكثر من 3 أجزاء ، فسيتم تخصيصها جميعًا ل catchall variable.
يوضح الجدول أدناه جميع المسارات التي سيطابقها هذا المسار:


Maps to
URL
Segments
controller = Home action = Index id = Null
/
0
controller = Home action = Index id = Null
/Home
1
controller = Home action = CatchallTest Id = Null
/Home/CatchallTest
2
controller = Home action = catchallTest id = Hello
/Home/CatchallTest/Hello
3
controller = Home action = catchallTest id = Hello catchall = How
/Home/CatchallTest/Hello/How
4
controller = Home action = catchallTest id = Hello catchall = How/Are
/Home/CatchallTest/Hello/How/Are
5
controller = Home action = catchallTest id = Hello catchall = How/Are/You
/Home/CatchallTest/Hello/How/Are/U
6
لاختبار ذلك، في كود Home Controller ، أضف Action method  باسم CatchallTest. ضع الكود التالي عليه:

public IActionResult CatchallTest(string id, string catchall)
{
    ViewBag.ValueofId = id;
    ViewBag.ValueofCatchall = catchall;
    return View();
}

لاحظ ان إضافنا parameter جديد باسم يسمى catchall إلى Action. وبهاي الطريقة مهما كان عدد parameters segments. سيخزن متغير ViewBag المسمى ValueofCatchall هذه القيمة المجمعة.
بعد ذلك، أضف CatchallTest View   داخل مجلد Views ➤ Home مع الكود الموضح أدناه:

@{ Layout = null; }
<!DOCTYPE html>
<html>
<head>
    <title>Routing</title>
</head>
<body>
    <h1>@@#Home@@# Controller, @@#CatchallTest@@# View</h1>
    <h2>Id value is: @ViewBag.ValueofId</h2>
    <h2>Catchall value is: @ViewBag.ValueofCatchall</h2>
</body>
</html>

سيتم في هذا View  عرض قيمة متغير ViewBag المسمى ValueofCatchall والذي يخزن قيمة catchall segment.
قم بتشغيل التطبيق وانتقل إلى
 URL - http://localhost:58470/Home/CatchallTest/Hello/How/Are/U.
جرب شغل التطبيق وحاول ترسل اكثر من parameters segments وشوف النتيحة وراسلنا اذا عندك ملاحظات او استفسارات