تعلم ASP.NET MVC


الدرس: مكافأة


الصفحة السابقة
نحن نقترب من نهاية الدورة. لقد بدأت في معرفة الكثير عن ASP.NET MVC وستتمكن الآن من إنشاء تطبيقات الويب الخاصة بك. أيضًا ، أقدم لك فصلاً أخيرًا على شكل مكافأة حيث سأخبرك عن الأشياء التي وعدتك بها وأشياء إضافية صغيرة. 

هيكل تطبيق Visual Studio MVC


لقد رأينا بالفعل أنه يمكننا إنشاء تطبيق MVC منذ البداية باستخدام عدد قليل من الملفات. فقط استخدم نموذج MVC واترك مربع MVC محددًا:
ASP.NET framework
اختيار نموذج التطبيق
لا تتردد في إساءة استخدام هذا النموذج ، فقد رأيت أنه يولد كل ما تحتاجه لإدارة المصادقة.
وبالمثل ، لديك العديد من الحزم المكونة وحتى إمكانية استخدام مرشح الأخطاء وعرض Error.cshtml الخاص به (والذي ستجده في الدليل المشترك).
هناك أيضًا مظهر كامل محدد مسبقًا يستند إلى Boostrap ، وهو إطار عمل CSS / JS تم إنشاؤه بواسطة Twitter ويوفر مجموعة كاملة من الأدوات لإنشاء مواقع تكيفية.
لا تتردد في إلقاء نظرة على التعليمات البرمجية التي تم إنشاؤها واستلهام نمط الموقع الافتراضي لإنشاء تطبيق ASP.NET MVC .

فائدة ترميز HTML


الآن ، أردت فقط أن أقول كلمة عن الأمن. بشكل عام ، يدير ASP.NET MVC الأمان بشكل جيد إلى حد ما ، باستثناء أنه يمكن أن تكون هناك حالات يمكن أن يكون موقعنا فيها معرضًا للخطر ومن الأفضل الانتباه إليه. أبسط الهجمات هو ما يسمى هجوم XSS   ويتكون من حقن كود ضار في صفحتنا. يمكن لهذا الكود الخبيث ببساطة "الإزعاج" ، ولكن يمكنها أيضًا محاولة سرقة المعلومات.
على سبيل المثال ، تخيل إجراء وحدة التحكم التالي:

public ActionResult Index()
{
    ViewBag.Id = "Nico";
    return View();
}
الذي يعرض العرض التالي:

<body>
    Bonjour @Html.Raw(ViewBag.Id)
</body>
ستقول كل شيء على ما يرام ... نحن فقط نعرض عبارة Hello Nico . ولكن إذا كانت السلسلة أشبه:

ViewBag.Id = "<script type=\"text/javascript\">\nalert('ahah, je t\\'ai eu !!');\n</script>";
سيكون لدينا رسالة قبيحة على صفحتنا على الويب:
ASP.NET framework
تم تنفيذ برنامج نصي ضار
حسنًا ، رسالة صغيرة كهذه ليست خطيرة جدًا ؛ حتى لو كان يسيء إلى الموقع بالكامل. ولكن يمكننا أن نتخيل إعادة التوجيه إلى نسخة زائفة من الموقع لمحاولة تصيد احتيالي:

ViewBag.Id = "<script type=\"text/javascript\">document.location.href=\"http://fr.openclassrooms.com\";</script>";
ها أنت ذا ، يمكنك أن ترتجف !!! ستتم إعادة توجيهك إلى موقع ArabClassroom . 

حسنًا ، سوف تخبرني أنك لن تكتب هذا أبدًا في وحدة التحكم الخاصة بك ... وآمل ذلك! ولكن تخيل أنك تنشر شيئًا يأتي من مكان ليس بالضرورة آمنًا ، مثل قاعدة بيانات مشتركة ، أو خدمة ويب ، أو ما هو أسوأ من ذلك ... من مدخلات المستخدم!
لذلك ، لقد حذرتك كثيرًا أنه لا يجب عليك أبدًا الوثوق بالمستخدم. هذا صحيح! ولكن ليس كل المستخدمين لديك قراصنة طموحون سيحاولون اختراق نظامك. من ناحية أخرى ، يمكن أن تكون بالدوار أو ببساطة مقاومة لأجهزة الكمبيوتر. لا تعتقد أن السبب هو أن لديك حقلاً متاحًا لإدخال سن لا يُدخل فيه اسمه الأول أو غيره عن غير قصد. هذا هو السبب في وجود آلية التحقق التي رأيناها وأنه يجب عليك التحقق بشكل منهجي مما أدخله المستخدم.

ولكن يمكن أن يكون هناك أيضًا بعض المستخدمين الذين يحاولون القرصنة أو يقرؤون المعلومات على الإنترنت والذين سيتحققون من أن نظامك آمن.
لذا فإن إدخال المستخدم هو ناقل الهجوم الرئيسي الذي ستحصل عليه. باستثناء أنه بشكل عام ، من الصعب جدًا إدارة إدخال علامات غريبة في أشكال HTML الخاصة بـ ASP.NET MVC لأنها محمية بشكل عام من هذا. وينطبق الشيء نفسه على المُدخلات في عنوان URL .

على سبيل المثال ، إذا كان لديك وحدة التحكم الخاصة بك في انتظار معرف في مُدخل مثل هذا:

public ActionResult Index(string id)
{
    ViewBag.Id = id;
    return View();
}
قد تقول أنه من السهل جدًا وضع جافا سكريبت أو HTML فيه. ولكن لا ، عناوين URL التالية:
  • /Home/Index?id=<h1>Youpi</h1>
  • /Home/Index?id= %3Ch1%3EYoupi%3C%2Fh1%3E
أو أي شيء من نفس النوع سينتج الخطأ التالي:
تم الكشف عن قيمة Request.QueryString التي يحتمل أن تكون خطرة من العميل (id = "<h1> Youpi </h1>").
والأمر نفسه إذا حاولت تصفح نموذج ينشر البيانات.
إذن ... أخيراً ، هل هي آمنة؟ هل نحن نمزح؟
ليس بالفعل ... بالفعل لأنه من المحتمل أن يتم العثور على أخطاء جديدة ولكن أيضًا بسبب وجود بعض الأخطاء المعروفة بالفعل. خذ على سبيل المثال المثال التالي الذي يبدو غير ضار:



@{
    ViewBag.Title = "Index";
}

@section scripts
{
    @if (!string.IsNullOrWhiteSpace(ViewBag.Id))
    {
        <script type="text/javascript">
            $(function () {
                var message = 'Bonjour, @ViewBag.Id';
                $("#montext").html(message).delay(1000).animate({
                    width: "70%",
                    opacity: 0.4,
                    marginLeft: "0.6in",
                    fontSize: "3em",
                    borderWidth: "10px"
                }, 1500);
            });
        </script>
    }
}
<h1 id="montext"></h1>
نستخدم JavaScript و jQuery لعرض اسم المستخدم عبر رسوم متحركة صغيرة من أجل المتعة. كود التحكم بسيط جدا:

public ActionResult Index(string id)
{
    ViewBag.Id = id;
    return View();
}
لذا ، سيكون كل شيء على ما يرام بالنسبة لعنوان URL مثل هذا: http://localhost: 49767/Home/Index/Nicolas. ولكن نظرًا لأننا مجموعة من المتسللين السيئين ، فسنجرب عنوان URL آخر. مثلا :
http://localhost:49767/Home/Index?id=\x3cscript\x3e%20alert(\x27AHAHA\x27)%20\x3c/script\x3e
وهناك الدراما:
ASP.NET framework
نص برمجي خبيث آخر
استخدمنا عنوان URL مشفرًا باستخدام جافا سكريبت ويمكننا حقن كل الشفرة التي نريدها ، على سبيل المثال شيء أقبح قليلاً من مربع الرسالة ...
إذن كيف تحمي نفسك من هذا النوع من الهجمات؟ يمكنك تخمينه إذا قرأت عنوان الفصل الفرعي جيدًا أو إذا كنت منتبهًا طوال البرنامج التعليمي. يجب علينا ترميز ما نكتبه على الصفحة. باستخدام محرك عرض ASPX ، يجب دائمًا استخدام <%= %> عوضا عن <% : %> وبالنسبة لمحرك عرض Razor ، يجب استخدام @ وليس Html.Raw () . آه ... ولكن هذا ما قمنا به وهذا يعمل بشكل جيد للغاية لـ HTML . ولكن بالنسبة إلى JavaScript ، استخدم المساعد التالي @Ajax.JavaScriptStringEncode   :

var message = 'Bonjour, @Ajax.JavaScriptStringEncode(ViewBag.Id)';
لقد فهمت المبدأ. قم دائمًا بتشفير ما تكتبه على الصفحة ، وتحقق دائمًا من إدخال المستخدم ، واحذر دائمًا ... لأنه في بعض الأحيان ، قد تكون هناك حاجة للسماح للمستخدم بإدخال HTML . تخيل على سبيل المثال تعليقات المدونة أو المنتدى. غالبًا ما يُسمح لكتابة HTML لإدراج صورة ، أو رابط إلى موقعها في توقيعها ، وما إلى ذلك. عند هذه النقطة ، يمكنك تعطيل التحقق من HTML لـ ASP.NET MVC عن طريق تزيين طرازه بالسمة AllowHtml   :

public class MonModele
{
    public int Id { get; set; }
    [AllowHtml]
    public string DuHtml { get; set; }
}
وهناك ... يجب أن نكون حذرين ، لأنه شريط مفتوح. عليك ترميز كل شيء.
ولكن بشكل عام ، من الأفضل استخدام مكتبة متخصصة في الكشف عن الهجمات. هذا هو الحال ، على سبيل المثال ، مع مكتبة AntiXSS  المجانية .
هناك العديد من الهجمات الأخرى (أخبرتك أيضًا عن اختطاف JSON ) لكنني لن أقدمها لك لأنني لست خبيرًا أمنيًا أيضًا. من المهم أن تكون على دراية بمخاطر الهجوم ، وهذا يسمح لك بالتدوين عن علم. لا تتردد في توثيق نفسك على الإنترنت.

استخدم "عنصر تحكم"


أخبرتك في الجزء الأول من الدورة أن إحدى نقاط القوة العظيمة لـ ASP.NET WebForms هي قدرتها على إعادة استخدام عناصر التحكم ، بينما مع ASP.NET MVC تكون أكثر دقة. هذه الجملة صحيحة وكاذبة في نفس الوقت. صحيح أنه من غير الممكن استخدام عناصر التحكم مع ASP.NET MVC كما يمكن للمرء أن يفعل ذلك مع WebForms لأنه يفتقر إلى كل إدارة حالة عناصر التحكم هذه ، المدعومة بشكل جيد من قبل WebForms ولكنها غير موجودة مع MVC .
من ناحية أخرى ، يحتوي ASP.NET MVC على أصل تعرفه بالفعل: المساعدون .  يبسطون كتابة كود HTML . وهذا ما نطلبه تقريبًا للتحكم في الويب. لقد رأينا مساعدين HTML ، مساعدين URL ، مساعدين Ajax ... سأريكم هنا المساعدين الرسامين الذين نسميهم باللغة الإنجليزيةChart Helper  .
سننتهز هذه الفرصة لإضافة لمسة نهائية غير مجدية تمامًا لتطبيقنا من خلال تقديم توزيع الأصوات في شكل رسم بياني.
أول شيء يجب القيام به ، قم بإضافة مرجع إلى تجميع System.Web.Helpers . سوف نستخدم الفئة Chart  . وبالتالي فهي فئة مساعدة ستتيح لنا إنشاء صورة يمكننا عرضها في واجهات عرضنا. ولعرض صورة ، نستخدم بالطبع علامة   <img>    :

<img src="@Url.Action("AfficheGraphique", new { id = ViewBag.Id })" />
أضعه على سبيل المثال في نهاية عرض PosterArray . الدقيقة الوحيدة هي أنه سيتم تعيين مصدر الصورة إلى نتيجة إجراء من قبل وحدة تحكم ، في هذه الحالة إجراء PosterGraphic لوحدة تحكم التصويت. هذا يعني أن المسار /Vote/AfficheGraphique/1 سيظهر لنا صورة.
وهذا ، يمكن أن يساعد مساعد الرسومات بشكل جيد للغاية:

public ActionResult AfficheGraphique(int id)
{
    List<Resultats> resultats = dal.ObtenirLesResultats(id);

    Chart graphique = new Chart(width: 600, height: 400)
    .AddTitle("Résultats")
    .AddSeries(
    xValue: resultats.Select(resto => resto.Nom).ToArray(),
    yValues: resultats.Select(resto => resto.NombreDeVotes.ToString()).ToArray());
    return File(graphique.GetBytes("png"), "image/png");
}
هنا ، أشير إلى أن إجراء وحدة التحكم يعيد لي ملفًا باستخدام الطريقة File   التي رأيناها بالفعل. وهي عبارة عن PNG تم بناؤها باستخدام المساعد الذي يمثل رسمًا مقاس 600 × 400 ، وعنوانه " Résultats " والذي يحمل أسماء المطاعم الموجودة على الإحداثي ، وعدد الأصوات في الإحداثي:
ASP.NET framework
عرض رسم بياني باستخدام MVC
لن أخوض في التفاصيل حول كل ما يمكننا القيام به كتخصيص للرسم البياني ، ستجد المعلومات على الإنترنت بسهولة بالغة. هناك عدة أنواع من الرسوم البيانية ، هنا اخترت الرسم البياني الشريطي ، ولكن يمكن أن يكون مخططًا دائريًا ، منحنيات ، إلخ. راجع http://msdn.microsoft.com/en-us/library/dd489233.aspx  .
الكثير لاستخدام هذا المساعد الذي يمكن أن يكون عمليًا للغاية والذي يبسط حياتنا إلى حد كبير. هل يمكنك أن تتخيل إذا كان عليك القيام بكل ذلك بنفسك؟

التوجيه حسب السمة


التوجيه حسب السمة جديد في ASP.NET MVC 5 .
هل تتذكر التوجيه؟ ولكن إذا تحدثنا عنه ، فقد نسيت.  إنها القدرة على مطابقة عنوان URL مع طريقة وحدة التحكم. حتى الآن ، قمنا بتحديد تكوين مساراتنا في فئة RouteConfig ، والتي يطلق عليها global.asax . بدا مثل:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
حسنا إذا كنت ترغب في ذلك الوقت قد انتهى. يمكنك تبسيط تعريف المسارات باستخدام السمات مباشرة على طرق وحدة التحكم. انظر بالأحرى:

 [Route]
public ActionResult Index()
{
    return View();
}
باستخدام هذه السمة ، تشير إلى التوجيه الذي يتوافق مع طريقة الفهرس لوحدة التحكم الرئيسية لمسار افتراضي. وتقليديًا نصل إليه باستخدام عنوان URL / أو /Home/Index . من ناحية أخرى ، ليس بواسطة / Home ، سنرى كيفية علاجها ...
هل لديك إجراء آخر لتعيينه؟ ما عليك سوى تزيين الطريقة الجديدة:

 [Route("Home/Afficher")]
public ActionResult Afficher()
{
    return View();
}
ويعمل السحر. يمكنك الوصول إلى هذا الإجراء عن طريق /Home/Show . حسنًا ، عندما أتحدث عن السحر ، إنها كلمة كبيرة جدًا. هذا بالطبع كود ... وإلى جانب ذلك ، يجب عليك تغيير الكود في RouteConfig لإخبار ASP.NET MVC أنك تريد استخدام نظام التوجيه هذا:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        //routes.MapRoute(
        // name: "Default",
        // url: "{controller}/{action}/{id}",
        // defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        //);
    }
}
تركت لك ما كان من قبل في التعليق. نحن فقط نضيف استدعاءا إلى الطريقة  MapMvcAttributeRoutes  لإنجاز المهمة.
بالطبع ، يمكننا وضع قيم اختيارية في طريقنا. على سبيل المثال ، للعثور على عمليتنا السابقة على الطريقة Index  . يمكننا استخدام الصيغة التالية:

 [Route("{Home?}/{Index?}")]
public ActionResult Index()
{
    return View();
}
نستخدم علامة الاستفهام للإشارة إلى أن المقطع اختياري. حتى نتمكن من الوصول إلى عنوان URL هذا مرة أخرى عبر / أو  /Home  أو  /Home/Index . يجب وضع الجزء الاختياري في أقواس متعرجة.
إذا كان هناك تعارض ، فسوف يلقي ASP.NET MVC خطأ. على سبيل المثال ، إذا حددنا الإجراءين على النحو التالي:

 [Route("{Home?}/{Index?}")]
public ActionResult Index()
{
    return View();
}

[Route("{Home?}/{Afficher?}")]
public ActionResult Afficher()
{
    return View();
}
ثم سيكون لدينا الخطأ التالي عند محاولة الوصول إلى URL / :
الطلب الحالي غامض بين طرق الإجراءات التالية:
System.Web.Mvc.ActionResult Index () على النوع DemoAttribute.Controllers.HomeController
System.Web.Mvc.ActionResult Display () على النوع DemoAttribute.Controllers.HomeController
لتمرير المُدخلات ، لا شيء أكثر بساطة:

 [Route("Home/Afficher/{id}")]
public ActionResult Afficher(string id)
{
    ViewBag.Id = id;
    return View();
}
والتي ستعمل على سبيل المثال مع عنوان URL للنوع /Home/Display/Youpi . إذا كنت ترغب في معالجة عدد صحيح ، فما عليك سوى تغيير نوع المُدخل ، كما كان من قبل:

 [Route("Home/Afficher/{id}")]
public ActionResult Afficher(int id)
{
    ViewBag.Id = id;
    return View();
}
وبالتالي ، سيعمل عنوان URL /Home/Afficher/1 بينما سيثير عنوان URL /Home/Afficher/Youpi استثناءً. بالطبع ، يمكن أن يكون لديك عدد صحيح فارغ ، لذلك لا يمكن تحويل Youpi id  وستكون قيمتها بذلك null  .
يمكننا أيضًا تحديد قيمة افتراضية للمُدخل بهذه الطريقة:

 [Route("Home/Afficher/{id=4}")]
public ActionResult Afficher(int id)
{
    ViewBag.Id = id;
    return View();
}
لذا فإن المسار /Home/Afficher/  سيكون مكافئًا لـ /Home/Afficher/4 .
من الممكن أيضًا تحديد القيود. على سبيل المثال ، إذا كنت أرغب تمامًا في أن يكون المُدخل عددًا صحيحًا ، فيمكنني تحديده على أنه قيد:

 [Route("Home/Afficher/{id:int}")]
public ActionResult Afficher(int id)
{
    ViewBag.Id = id;
    return View();
}
وبالتالي ، سيعمل عنوان URL /Home/Afficher/1 بينما لن يعثر عنوان URL /Home/Afficher/Youpi  على إجراء مطابق.
يرجى ملاحظة أن هذا يختلف تمامًا عما كان لدينا من قبل. إذا لم يتطابق النوع مع المُدخل في المثال السابق ، فقد كان هناك استثناء تم طرحه. هنا ، القيد غير صالح ، لذلك الإجراء غير مؤهل. لذلك في حالتنا ليس لدينا أي عمل يستجيب لهذا الطريق.
غالبًا ما يكون كلاسيكيًا أن وحدة التحكم لها مساراتها التي تبدأ جميعها بالبادئة نفسها:

public class HomeController : Controller
{
    [Route("Home/{Index?}")]
    public ActionResult Index()
    {
        return View();
    }

    [Route("Home/Afficher/{id=4}")]
    public ActionResult Afficher(int id)
    {
        ViewBag.Id = id;
        return View();
    }

    [Route("Home/Test")]
    public ActionResult Test()
    {
        return View();
    }
}
في هذه الحالة ، من الممكن استخدام بادئة على مستوى الفئة:

 [RoutePrefix("Home")]
public class HomeController : Controller
{
    [Route("{Index?}")]
    public ActionResult Index()
    {
        return View();
    }

    [Route("Afficher/{id=4}")]
    public ActionResult Afficher(int id)
    {
        ViewBag.Id = id;
        return View();
    }

    [Route("Test")]
    public ActionResult Test()
    {
        return View();
    }
}
في هذا المثال ، لا يمكنني تعيين المسار / لأنه في هذه الحالة يصبح {Home} إلزاميًا. لإعادة إنتاج ما كان لدينا من قبل ، يجب علي استخدام [RoutePrefix("{Home?}")]
إذا كنت لا تريد استخدام البادئة لطريقة معينة ، يمكنك تحميل هذه العملية بشكل زائد مع ~ :

 [Route("~/CeQueJeVeux/Afficher/{id=4}")]
public ActionResult Afficher(int id)
{
    ViewBag.Id = id;
    return View();
}
تعال ، نعود إلى القيود قليلاً ، وهنا قائمة:
القيد الوصف مثال
alpha جميع الأحرف الأبجدية الرقمية {x:alpha}
bool منطقي {x:bool}
datetime تاريخ {x:datetime}
decimal عشري واحد {x:decimal}
double مزدوج {x:double}
float تعويم {x:float}
guid GUID {x:guid}
int عدد صحيح {x: int}
length سلسلة الطول المطلوب (أو ضمن النطاق المطلوب) {x: length (6)}
{x: length (1.20)}
long طويل {x:long}
max عدد صحيح بقيمة قصوى {x:max(10)}
maxlength سلسلة بطول أقصى {x:maxlength(10)}
min عدد صحيح بحد أدنى للقيمة {x: min (10)}
minlength سلسلة من الحد الأدنى للطول {x: minlength (10)}
range عدد صحيح في فاصل زمني {x: range (10.50)}
regex تعبير عادي {x: regex (^ \ d {3} - \ d {3} - \ d {4} $)}
من الممكن أيضًا إعطاء اسم لطريق باستخدام سمة الاسم:

 [Route("{Index?}", Name = "Accueil")]
public ActionResult Index()
{
    return View();
}
لذلك ، يمكنك إنشاء عنوان URL لهذا المسار باسمه فقط:

<a href="@Url.RouteUrl("Accueil")">Accueil</a>
لاحظ أن نظام التوجيه هذا متوافق تمامًا مع النظام السابق ويمكننا استخدام كليهما في نفس الوقت.

ASP.NET Web API


نحن في المستقبل ، وقمت بإثراء تطبيق اختيار المطاعم لدينا بحيث يكون ضروريًا ويستخدمه الكثير من الناس. لقد طلبوا منك إصدارًا للجوال وقمت بإنشاء الكثير من واجهات العرض التي تلحقها .Mobile بحيث يكون تطبيق الويب قابلاً للاستخدام بالكامل على جهاز محمول.
إنهم يطلبون الآن إصدارًا لنظام التشغيل 10 Windows ولديك فكرة إنشاء تطبيقات أحداث أصلية على هواتف الواقع المعزز من خلال الاستفادة من جميع أجهزة استشعار الهواتف الذكية لدينا مثل الجيروسكوب ومقياس التسارع والكاميرا.
للقيام بذلك ، تحتاج إلى أن تكون قادرًا على الوصول إلى نموذجك ومن المحتمل أن تكون وحدات التحكم الخاصة بك في شكل REST APIs . لذا نعم ، نحن نعرف كيف نجعل وحدات التحكم الخاصة بنا ترسل JSON مرة أخرى ، وهذا خيار يمكن تصوره تمامًا لكشف المسارات للمستهلكين ولكن هناك أبسط: ASP.NET Web API .
Web API عبارة عن إطار عمل يستند إلى ASP.NET متخصص في إنشاء خدمات HTTP بطريقة بسيطة وفعالة. لن أخوض في تفاصيل كيفية استخدامه ، ولكن سأوضح لك مثالًا صغيرًا فقط حتى تتمكن من معرفة الغرض منه.
لبدء هذا المثال ، سأبدأ بإنشاء تطبيق ويب ASP.NET جديد. ستتمثل الدقة في تحديد مربع واجهة برمجة تطبيقات الويب الذي يسمح بتنشيط وظائف واجهة برمجة تطبيقات الويب:
ASP.NET framework
تمكين ميزات Web API
ننتهي بتطبيق ويب يكون هيكله قريبًا جدًا من تطبيق ASP.NET MVC . سنقوم بإنشاء نموذج بسيط للغاية حتى لا نضيع الوقت في هذه المكافآت ، ولكن يمكنك استرداد نموذجنا للمطاعم بالكامل الذي تم إنشاؤه في تطبيقنا الاخير:

public class Resto
{
    public int Id { get; set; }
    public string Nom { get; set; }
}

public class Restos
{
    public List<Resto> ChargerRestaurants()
    {
        return new List<Resto>
        {
            new Resto { Id = 1, Nom = "Resto pinière"},
            new Resto { Id = 2, Nom = "Resto pinambour"},
            new Resto { Id = 3, Nom = "Resto ride"},
        };
    }
}
سنقوم الآن بإنشاء وحدة تحكم ، يحدث هذا بنفس الطريقة المذكورة أعلاه باستثناء أنه يجب عليك اختيار وحدة تحكم Web API 2 :
ASP.NET framework
إضافة وحدة تحكم Web API
أطلق عليه RestaurantController ويمكنك أن ترى أن Visual Studio يولد فئة لنا مشتقة من ApiController   :

public class RestaurantController : ApiController
{
}
أضف الآن هذين الإجراءين في وحدة التحكم:

public class RestaurantController : ApiController
{
    public IEnumerable<Resto> GetTousLesRestos()
    {
        return new Restos().ChargerRestaurants();
    }

    public IHttpActionResult GetResto(int id)
    {
        Resto resto = new Restos().ChargerRestaurants().FirstOrDefault(r => r.Id == id);
        if (resto == null)
        {
            return NotFound();
        }
        return Ok(resto);
    }
}
وهذا كل شيء !
يمكن الوصول إلى وحدتي التحكم لدينا عبر عناوين URL التالية:
  • http://localhost: 57673/api/restaurant
  • http://localhost: 57673/api/restaurant/2
لماذا هذه الطرق؟ افتح ملف WebApiConfig.cs الموجود في دليل App_Start وسوف تفهم السبب:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
    );
نجد تعريفًا للمسار كما هو الحال مع ASP.NET MVC . وبالتالي تكون المسارات افتراضيًا /api/the_controller_name . في هذه الحالة ، تسمى وحدة التحكم لدينا Restaurant . ومع ذلك ، لا يوجد إجراء. كيف يوجه التوجيه الطريقة الصحيحة؟
بالاتفاقية بالطبع. هنا ، من خلال الاستعلام عن عنواني URL هذين ، نطلب موردًا يمكن الوصول إليه عبر طريقة GET لبروتوكول HTTP . للعثور على إجراء مطابق ، ما عليك سوى وضعه في Get . هذا هو السبب في أن طريقتين تبدأ بـ Get (وكل ما نضعه بعد ذلك) . إذا أردنا إجراء تعديل على الموارد ، لكنا قد استخدمنا طريقة POST لبروتوكول HTTP ، وكنا قد كتبنا طريقة مسبوقة بالبريد ... تعمل
هذه الاتفاقية أيضًا مع طريقتين PUT و DELETE .
من الممكن أيضًا تحديد الطريقة التي نريد استخدامها بفضل السمة:

 [HttpGet]
public IHttpActionResult TrouveResto(int id)
{
    Resto resto = new Restos().ChargerRestaurants().FirstOrDefault(r => r.Id == id);
    if (resto == null)
    {
        return NotFound();
    }
    return Ok(resto);
}
ستقول لي أنه يشبه MVC ، هذا هو الهدف !!  هذا يعني أنه يمكنك أيضًا تغيير المسار لإخباره باستخدام الإجراء الذي يمكنك تقديمه في عنوان URL ...
أمرر لك تفاصيل Web API لأنها ستتطلب دورة أطول ، ولكن قبل الانتهاء من هذا الفصل ، سأعرض لك نتيجة طلبنا. واحدة من أفضل الأدوات لتقديم طلبات REST هي fiddler الذي يمكنك تنزيله من http://www.telerik.com/download/fiddler  . أمرر لك تركيبه واستخدامه ، إذا كان الموضوع يهمك ، فلا تتردد في استشارة الدروس حول هذا الموضوع.
لذلك سنقوم بتنفيذ طلب Get عبر عنوان :URL http://localhost: 57673/api/restaurant/3
ASP.NET framework
طلب RET في GET مع Fiddler
والنتيجة هي JSON
ASP.NET framework
نتيجة الطلب في JSON
هذه بالطبع نتيجة الطريقة:

 [HttpGet]
public IHttpActionResult TrouveResto(int id)
{
    Resto resto = new Restos().ChargerRestaurants().FirstOrDefault(r => r.Id == id);
    if (resto == null)
    {
        return NotFound();
    }
    return Ok(resto);
}
هنا ، نستخدم طريقة Ok  لإرجاع المطعم في JSON وفي نفس الوقت رمز HTTP 200 . مع طريقة NotFound ، نعيد بالطبع رمز الخطأ 404.
لاحظ أنه يمكننا بسهولة إرجاع قائمة العناصر باستخدام الطريقة:

public IEnumerable<Resto> GetTousLesRestos()
{
    return new Restos().ChargerRestaurants();
}
ما عليك سوى إرجاع IEnumerable (أو أي كائن) ، وسيتم إجراء تسلسل له تلقائيًا في JSON :

 [{"Id":1,"Nom":"Resto pinière"},{"Id":2,"Nom":"Resto pinambour"},{"Id":3,"Nom":"Resto ride"}]
هذا بالطبع عملي جدًا ، ولكن هنا ستعيد دائمًا رمز 200 يشير إلى أن المورد قد تم الرد عليه بشكل صحيح. إذا رغبت لسبب ما في أن تتمكن من إرجاع رمز 404 (أو لما لا رمز 403 للإشارة إلى مشكلة وصول) ، فسيتعين عليك العودة إلى البناء السابق وإرجاع كائن يتم تنفيذه IHttpActionResult  .
ولكن بالمناسبة ، لقد تحدثت فقط عن JSON في هذا الفصل لأنه صحيح أن هذا التنسيق ضروري في REST APIs . ولكن كن على علم أنه من الممكن أيضًا الحصول على XML بدلاً من JSON ودون الحاجة إلى القيام بأي شيء. للحصول على XML ، عليك فقط أن تطلبه أثناء طلبنا ويتم ذلك في الرؤوس عن طريق تحديد الرأس accept:application/xml   :
ASP.NET framework
طلب REST للحصول على XML
وتُعيد في المقابل:

<Resto xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/DemoWebApi.Models"><Id>3</Id><Nom>Resto ride</Nom></Resto>
إذا كان هذا العنوان مفقودًا ، فإن القيمة الافتراضية هي JSON .
الكثير لهذه الجولة السريعة من ASP.NET WEB API . لم أظهر لك الكثير ويمكنك أن تقول لنفسك أنك قمت بالفعل بالتعامل مع واجهات برمجة تطبيقات REST الصغيرة بسهولة. ولكن ضع في اعتبارك أن إنشاء خدمات REST هو مهمة معقدة بشكل عام بمرور الوقت ، نظرًا لأنها مفتوحة المصدر ، يجب أن تكون آمنة ، وتستخدم بروتوكول HTTP بشكل مثالي وإدارة الإصدار بشكل صحيح. ASP.NET Web API يعالج كل هذا بشكل جيد للغاية.
ملاحظة: يعمل التوجيه حسب السمة التي رأيناها أعلاه مع Web API أيضًا.  

باختصار


  • ضع في اعتبارك أن تطوير موقع ويب يعني تعريض نفسك لهجمات محتملة. يجب عليك دائمًا حماية نفسك وأحد القواعد هو دائمًا ترميز ما يأتي من القيم غير الآمنة بالضرورة.
  • المساعدون عمليون جدًا لتبسيط التطوير. يعمل مساعد الرسومات على تسهيل إنشاء رسومات بجميع أنواعها.
  • يعد التوجيه حسب السمة جديدًا في ASP.NET MVC 5 ويسمح بتبسيط تعريف المسارات.
  • تجعل واجهة برمجة تطبيقات الويب من السهل جدًا إنشاء REST APIs .

خلاصة عامة


هذا كل شيء ، لقد وصلت أخيرًا إلى نهاية هذه الدورة. لا يسعني إلا أن أهنئك لأنه إذا كنت منتبهًا ، فأنت جاهز تمامًا لإنشاء مواقع الويب الخاصة بك الآن. وهذا إلى حد كبير ما فعلته مع تطبيقنا الجميل ، لأنك فعلت كل ذلك تقريبًا.
إذن ماذا فعلنا في هذه الدورة؟
لقد قمنا بالفعل بمراجعة ما كان عليه موقع الويب مع التذكيرات على HTML و CSS و JavaScript وهي لغات أساسية لإنشاء موقع الويب. ثم اكتشفنا MVC وفلسفته ، بالإضافة إلى ASP.NET التي تزودنا بكل اللبنات التي نحتاجها لجعل مواقعنا أكثر ديناميكية.
لقد درسنا النموذج باستخدام Entity Framework ، والعرض باستخدام محركات عرض ASPX و Razor ، ثم وحدة التحكم وكل ما يمكننا القيام به. وهي بالفعل كثيرة !!
باستثناء أننا لم نتوقف عند هذا الحد ، حريصون على معرفة أننا ، تحدثنا عن الاختبارات والطرق والمصادقة و Ajax ... وما إلى ذلك. ستتم إضافة كل هذه الأشياء إلى MVC للسماح بإنشاء تطبيقات ويب متماسكة وكاملة.
وكل ذلك بلغتنا المفضلة: C# . ماذا ايضا!
آمل أن تكون هذه الدورة قد حققت توقعاتك وأنك ستستمر في إنشاء مواقع ويب ولما لا تحسن التطبيق الخاص بنا ... لأنه صحيح أن الأشياء مفقودة وأنه بالإضافة إلى ذلك لا ليست جميلة حقا. تذكر أنه من خلال التدريب سوف تتقدم وأنك ستصبح جيدا في ASP.NET MVC . لم أستطع أن أريكم كل شيء في ASP.NET MVC ، ولكن لديك حقًا كل ما تحتاجه للبدء. لا تتردد في الرجوع إلى الموارد الأخرى ، وكن أيضًا فضوليًا بشأن المشاريع المجتمعية التي يمكن أن تساعدك كثيرًا.
حظا سعيدا وتتطور بشكل جيد.