تعلم ASP.NET MVC


الدرس: التقليص في التعليمات البرمجية الخاصة بك مع المساعدين وواجهات العرض الجزئية


الصفحة السابقة

مساعدين HTML (helpers)


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

<div>Je suis la vue index</div>
<input type="text" id="nom" value="@Model.Resto.Nom" />
<input type="text" id="telephone" value="@Model.Resto.Telephone" />
<input type="submit" value="Envoyer" />
باستخدام مساعدين HTML ! إليك على سبيل المثال ما يعادل هؤلاء المساعدين المشهورين:

<div>Je suis la vue index</div>
@Html.TextBox("nom", Model.Resto.Nom)
@Html.TextBox("telephone", Model.Resto.Telephone)
<input type="submit" value="Envoyer" />
انظر كم هو بسيط لاستبدال بناء جملة HTML لإدخال نوع النص. سيقوم هذا المساعد بإنشاء HTML التالي لنا:

<input id="nom" name="nom" type="text" value="La bonne fourchette" />
<input id="telephone" name="telephone" type="text" value="1234" />
وهو بالضبط ما سألناه. في الواقع ، إنه أفضل لأنه ملأ سمة المعرف وسمة الاسم بالمُدخل الذي مررنا إليه. لذا ، لا يوجد خطر نسيان السمة كما فعلنا. على أي حال ... أقول "نحن" ، لكن أنا في الواقع ؛ أنا متأكد من أنك لن تنسى ذلك .
هؤلاء المساعدون لديهم العديد من الأحمال الزائدة(overloads) المختلفة. هنا استخدمت التحميل الزائد الذي يسمح لي بتحديد اسم مربع النص وقيمته. تسمح لي الأحمال الزائدة الأخرى بالعمل بشكل أدق على HTML الذي تم إنشاؤه ، على سبيل المثال لإضافة خصائص إضافية ، النمط ...
هنا على سبيل المثال ، يمكنني الإشارة إلى أن نص علامة <input> سيكون له نمط اللون الأحمر:

@Html.TextBox("nom", Model.Resto.Nom, new { style = "color:red" })
الذي يعطيني HTML التالي:

<input id="nom" name="nom" style="color:red" type="text" value="La bonne fourchette" />
ولكن كان يمكنني أيضًا تقديم اسم فئة CSS :

@Html.TextBox("nom", Model.Resto.Nom, new { style = "color:red", @class  = "ma-css" })
مما يمنحنا:

<input class="macss" id="nom" name="nom" style="color:red" type="text" value="La bonne fourchette" />
نستخدم لإضافة سمات HTML إلى كائن مجهول اسمه الخاص به يتوافق مع اسم سمات HTML التي نريد وضعها. لذلك ، بإنشاء كائن مجهول بخاصية تسمى "النمط" ، أخبر المساعد بأنني أريده أن يضيف سمة النمط إلى علامة HTML .
لاحظ أنه يتم الحصول على سمة class باستخدام خاصية مجهولة تحمل نفس الاسم ، ولكن مسبوقة بـ @ car class  هي كلمة رئيسية محجوزة لـ C# ، تُستخدم بالطبع لإنشاء فئات ...
هناك مساعد فقط لجميع علامات النموذج. على سبيل المثال ، يمكن إنشاء مربع اختيار ومربع نص غير قابل للتحرير بمساعدة المساعدين التاليين:

<div>Je suis la vue index</div>
@Html.Label("estMajeur", "Cochez la case si vous êtes majeur")
@Html.CheckBox("estMajeur", true)
<input type="submit" value="Envoyer" />
وسيكون لدينا هذا العرض:
ASP.NET framework
مربع اختيار مع مساعد Html.CheckBox
باستخدام HTML التالي:

<label for="estMajeur">Cochez la case si vous êtes majeur</label>
<input checked="checked" id="estMajeur" name="estMajeur" type="checkbox" value="true" /><input name="estMajeur" type="hidden" value="false" />
<input type="submit" value="Envoyer" />
لاحظ أنه في HTML الجيد ، يجب أن تتوافق السمة for الخاصة بالتسمية مع معرف خانة الاختيار المرفقة بها للسماح بتحديدها من نص التسمية. هذه هي الحالة هنا ، المُدخل الأول من المساعد Html.Label   هي معرف خانة الاختيار.
قد يلاحظ القراء العاديون أن HTML الذي تم إنشاؤه ليس بالضبط ما كنا نتوقعه. في الواقع ، هناك إدخال من نوع خانة الاختيار يحمل اسم estMajeur ولكن أيضًا إدخال من النوع المخفي الذي يحمل نفس الاسم. يؤدي ذلك إلى تبسيط استرداد قيمة خانة الاختيار على جانب وحدة التحكم.
سترى أيضًا في المثال السابق أن المساعد يقدم ترميزًا تلقائيًا. سنعود إلى هذا بعد قليل.
الآن دعنا ننتقل إلى اثنين من المساعدين المحددين الذين سيقومون بإنشاء قوائم الاختيار والتي ستولد علامة HTML داخليًا <select>  . هؤلاء هم المساعدون Html.DropDownList   و Html.ListBox  . الميزة الخاصة لهؤلاء المساعدين هي أنه يجب ملئهم مسبقًا بقائمة من المقترحات. لهذا ، نستخدم كائنًا SelectList  سنطعمه مع قائمة المقترحات. تخيل على سبيل المثال أنني أرغب في الحصول على قائمة منسدلة مع جميع المطاعم الخاصة بي ، يمكنني إنشاء هذه القائمة على النحو التالي من وحدة التحكم:

List<Models.Resto> listeDesRestos = new List<Resto>
{
    new Resto { Id = 1, Nom = "Resto pinambour", Telephone = "1234" },
    new Resto { Id = 2, Nom = "Resto tologie", Telephone = "1234" },
    new Resto { Id = 5, Nom = "Resto ride", Telephone = "5678" },
    new Resto { Id = 9, Nom = "Resto toro", Telephone = "555" },
};

ViewBag.ListeDesRestos = new SelectList(listeDesRestos, "Id", "Nom");
SelectList  تم بناء الكائن من قائمة المطاعم ، مع العلم أنه تم تمريره أيضًا باسم المُعرف مما يجعل من الممكن تحديد مطعم بشكل فريد ، في هذه الحالة هو معرف فئة Resto  (سيتم العثور على هذه القيمة في خاصية value  العلامة <option> ) . وبالمثل ، فإننا نمررها باسم الخاصية التي ستكون بمثابة وصف للقيمة ، وهنا هي خاصية Nom  الفئة Resto  .
يتم تمرير كل هذا على سبيل المثال في ViewBag  وسيتم استخدامه في العرض مع:

@Html.DropDownList("RestoChoisi", (SelectList)ViewBag.ListeDesRestos)
يتوافق المُدخل الأول من المساعد بشكل تقليدي مع معرف HTML لعنصر التحكم والمُدخل الثاني هيSelectList  .
تنبيه ، يجب ألا يكون الاسم الذي يحدد علامة HTML هو نفسه أحد خصائص نموذج العرض ، نظرًا لآلية ربط النموذج التي سنكتشفها لاحقًا. إنه خطأ كلاسيكي.
لذا نحصل على لفيفة تمرير لطيفة ، مطوية ثم مفككة:
ASP.NET framework
القائمة المنسدلة
و HTML المصاحب كما يلي:

<select id="RestoChoisi" name="RestoChoisi">
    <option value="1">Resto pinambour</option>
    <option value="2">Resto tologie</option>
    <option value="5">Resto ride</option>
    <option value="9">Resto toro</option>
</select>
يمكننا أن نرى أن معرّفات المطاعم موجودة في خاصية القيمة لكل علامة <option>   وأن اسم المطعم يتوافق مع وصف خيار التحديد.
قد تجد من المدهش أنني قمت بإنشاء القائمة المنسدلة من وحدة التحكم وليس من طريقة العرض. في الواقع ، يمكننا أن نرى وحدة التحكم على أنها تعد النموذج ليتم عرضه بواسطة العرض. من الممكن أيضًا إنشاء العرض ولكن بشكل عام لا أحد يفعل ذلك لأنه يزيد العرض بشكل ملحوظ ويجعله أقل قابلية للقراءة.
لاحظ أنه من الممكن التحديد المسبق لعنصر من القائمة إذا أردنا ذلك لأنه يتم وضعه افتراضيًا على العنصر الأول. في هذه الحالة ، يكفي إضافة مُدخل جديد إلى مُنشئ SelectList  لتمرير معرف العنصر الذي سيتم تحديده:

ViewBag.ListeDesRestos = new SelectList(listeDesRestos, "Id", "Nom", 5);
وهنا ، عندما يتم عرض عنصر التحكم ، سيتم تحديد مطعم رحلتي مسبقًا:
ASP.NET framework
القائمة المنسدلة مع عنصر محدد مسبقًا
يتم تكييف HTML وفقًا لذلك:

<select id="RestoChoisi" name="RestoChoisi">
    <option value="1">Resto pinambour</option>
    <option value="2">Resto tologie</option>
    <option selected="selected" value="5">Resto ride</option>
    <option value="9">Resto toro</option>
</select>
حسنًا ، الأمر نفسه ، لن أخوض في كل المساعد ، ولكن دعنا نرى واحدًا آخر سيخدمك: إنه المساعد الذي يولد علامة النموذج <form>  .
ترتبط علامة النموذج ، وخصوصًا صفتها action ، ارتباطًا وثيقًا بالطريق الذي نريد إرسال المعلومات إليه. تذكر أن علامة النموذج لها هذا الرأس:

<form action="/MonControleur/MonAction" method="post">
    ...
</form>
مع العلم أن الطريقة يمكن أن تكون إما نشر أو الحصول عليها. الشيء هو أنه ليس من السهل دائمًا معرفة عنوان URL لإرسال البيانات إليه. في حالتنا التبسيطية ، إذا كنت ترغب في إرسال البيانات إلى طريقة Index في وحدة التحكم Home ، فما عليك سوى إدخال العنوان /Home/Index . بسيط. ولكن هذا لأن قواعد التوجيه الخاصة بنا بسيطة للغاية (بالمناسبة ، هناك واحد فقط!). إذا كان الأمر أكثر تعقيدًا قليلاً ، أو إذا تغيرت تعريفات المسار على طول الطريق ... 
 لا يمكنني ضمان استمرار عنوان URL /Home/Index في استدعاء وحدة التحكم المناسبة والطريقة الصحيحة. 
سيظل الأمر أبسط بكثير إذا كان بإمكاني أن أقول لها أن ترسل إلى طريقة تحكم أعرفها ، بدلاً من عنوان لا أعرف إذا كان سيتغير ...
حسنا سمعنا ASP.NET MVC.  في الواقع ، كان قد توقع حاجتنا قبل أن نحصل عليها ، ولكن ذلك لأنه كبير للغاية ... 
للقيام بذلك ، ما عليك سوى استخدام مساعد النموذج وستكون مسؤولة عن إنشاء عنوان URL من اسم وحدة التحكم وأحد طرقها. المساعد المعني Html.BeginForm   يأتي ويذهب مع صديقه Html.EndForm  . نستخدمها على النحو التالي:

<div>Je suis la vue index</div>
@{Html.BeginForm("Index", "Home");}
@Html.Label("estMajeur", "Cochez la case si vous êtes <strong>majeur</strong>")
@Html.CheckBox("estMajeur", true)
<input type="submit" value="Envoyer" />
@{Html.EndForm();}
يولد لنا HTML التالي:

<form action="/Home" method="post">
    <label for="estMajeur">Cochez la case si vous êtes <strong>majeur</strong></label>
    <input checked="checked" id="estMajeur" name="estMajeur" type="checkbox" value="true" /><input name="estMajeur" type="hidden" value="false" />
    <input type="submit" value="Envoyer" />
</form>
يمكننا أن نرى أن سمة action  العلامة form  معبئة بشكل صحيح. إلى جانب ذلك ، ترى أن ASP.NET فعل ما يريد ، فقد وضعنا في الإجراء /Home عندما كان بإمكاننا وضعنا / أو آخر /Home/Index . في الواقع ، فإنه يدير مع نظام التوجيه لوضع عنوان URL صالح. يمكنك المحاولة باستخدام قيم طرق أخرى ، على سبيل المثال:

@{Html.BeginForm("Index2", "Home");}
وهذه المرة ، يلزمها إنشاء عنوان URL الكامل لنا:

<form action="/Home/Index2" method="post">
هنا ، الإجراء الافتراضي المحدد هو طريقة النشر. يمكننا تغييره بفضل التحميل الزائد للطريقة:

@{Html.BeginForm("Index2", "Home", FormMethod.Get);}
وسيكون لدينا:

< ;form action="/Home" method="get"> ;
ستدرك أن هذه هي الطريقة BeginForm  التي تكتب علامة الافتتاح <form>  وأن هذه هي الطريقة EndForm  التي تكتب علامة الإغلاق. من الممكن تبسيط الكتابة بفضل الكلمة الأساسية using  . إذن ، هذا يعادل ما رأيناه سابقًا:

<div>Je suis la vue index</div>
@using (Html.BeginForm("Index", "Home"))
{
    @Html.Label("estMajeur", "Cochez la case si vous êtes <strong>majeur</strong>")
    @Html.CheckBox("estMajeur", true)
    <input type="submit" value="Envoyer" />
}
يمكنك استخدام أي من الصيغ بحرية بناءً على ما تجده واضحًا في الوقت المناسب ؛ شخصيا ، أنا من محبي البناء مع using   .
لاحظ أن جميع المساعدين تقريبًا لديهم زيادة في التحميل حيث يمكننا تحديد سمات HTML ، وهذا هو الحال أيضًا مع مساعد النموذج. حتى نتمكن من إرسال النموذج إلى صفحة جديدة على سبيل المثال ، يمكننا استخدام الكود التالي:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { target = "_blank" }))
{
    ...
}
مما سيعطي:

< ;form action="/Home" method="post" target="_blank"> ;

المساعدين المكتوبون بقوة


إنهم يعملون مثل المساعدين الذين رأيناهم للتو ، ولكن بدلاً من العمل مع الأوتار ، فهم يعملون بفضل قوة تعبيرات Lamda .
على سبيل المثال ، رأينا مساعدًا فوقها مباشرةً أنشأ منطقة نص قابلة للتحرير:

@Html.TextBox("nom", Model.Resto.Nom)
يمكن كتابة هذا أيضًا:

@Html.TextBoxFor(model => model.Resto.Nom)
هؤلاء المساعدون متكافئون تقريبًا ، لكن الثاني يستفيد ، بفضل تعابير Lamda ، من دعم الإكمال التلقائي ؛ هذا يبسط أيضا أي إعادة هيكلة. لا حاجة للتحقق من كل السلاسل في المساعد إذا تغيرت خاصية النموذج من أي وقت مضى.
بشكل عام ، هناك مساعد مطبوع بقوة لكل مساعد متاح ، يتم ببساطة إضافته بواسطة For .
لكنهم لا ينتجون نفس كود HTML بالضبط. إليك ما يولده الأول:

< ;input id="nom" name="nom" type="text" value="La bonne fourchette" /> ;
والثاني:

< ;input data-val="true" data-val-required="Le champ Nom est requis." id="Resto_Nom" name="Resto.Nom" type="text" value="La bonne fourchette" /> ;
في الواقع هو نفسه تقريبا. بالإضافة إلى اسم الحقل الذي يختلف اختلافًا طفيفًا ، هناك بالفعل إدخال من نوع النص ذي القيمة الجيدة. ولكن هناك سمات إضافية data-val   و data-val-required  . يمكننا أن نسخر منه الآن لأنهم لن يخدمونا بعد. ومع ذلك ، سيتم استخدامها لاحقًا عندما نكتشف التحقق من الصحة. إنه في الواقع بسبب نموذجنا. تذكر أن الفصل Resto   هو:

 [Table("Restos")]
public class Resto
{
    public int Id { get; set; }
    [Required]
    public string Nom { get; set; }
    public string Telephone { get; set; }
}
تبدأ في الشك من أين أتت. ونعم ، السمة [Required]   الموجودة فوق خاصية الاسم. للتذكير ، يشير إلى أن Resto  الاسم إلزامي. هذا له تأثير جعل حقل قاعدة البيانات في " not null "؛ ولكن يمكنك أن ترى أن لها تأثيرًا آخر في رأينا. سنعود إلى هذا عندما نتحدث عن التحقق من الصحة.
إذا استخدمنا هذا المساعد مع الخاصية Telephone  ، التي ليس لها سمات:

@Html.TextBoxFor(model => model.Resto.Telephone)
كان سيكون لدينا HTML البسيط التالي:

<input id="Resto_Telephone" name="Resto.Telephone" type="text" value="1234" />
هذه الخصائص تزيين خصائص لها وظائف أخرى. خذ على سبيل المثال المساعد LabelFor الذي يستخدم بشكل عام بالتزامن مع المساعد TextBoxFor للإعلان عن وصفه:

@Html.LabelFor(model => model.Resto.Telephone)
@Html.TextBoxFor(model => model.Resto.Telephone)
نحصل على العرض التالي:
ASP.NET framework
التسمية بدون سمة على خاصية النموذج
ملأ الملصق باسم العقار ، في هذه الحالة Telephone  . مشكلة ، افتقد لهجة (é)
للتعبير عن ذلك ، ما عليك سوى تعديل النموذج بإضافة سمة:

 [Table("Restos")]
public class Resto
{
    public int Id { get; set; }
    [Required]
    public string Nom { get; set; }
    [Display(Name="Téléphone")]
    public string Telephone { get; set; }
}
وهنا يحدث السحر ، نحصل على لهجتنا:
ASP.NET framework
التسمية بسمة تغير تصنيفها
يستطيع المساعدون قراءة السمات الاختيارية التي يمكننا وضعها على العناصر التي نريد عرضها. هنا ، يتم وضع هذه السمات في نموذجنا ، لكنها كانت ستعمل بنفس الطريقة على نموذج العرض.
من المثير للاهتمام ملاحظة أنه يمكننا تمرير المُدخلات (بالنسبة لـ BeginForm  ) إلى الإجراءات. خذ على سبيل المثال جهاز التحكم الوهمي ، لأنه لم يتم إنشاؤه بعد ، مما يسمح لنا بتعديل مطعم RestaurantController  : ، وكذلك طريقته ModifierRestaurant  . يمكننا إنشاء رابط لهذا الإجراء باستخدام المساعد التالي:

@Html.ActionLink("Modifier le restaurant", "ModifierRestaurant", "Restaurant")
(في المُدخل الأول ، هذا هو الاسم الذي يظهر في الارتباط. يتوافق التالي مع اسم الإجراء الذي يتم استدعاؤه والأخير هو اسم وحدة التحكم المراد إنشاء مثيل لها ) . هذا يولد لنا هذا HTML :

< ;a href="/Restaurant/ModifierRestaurant"> ;Modifier le restaurant< ;/a> ;
من الممكن تمرير المُدخلات إلى العمل ModifierRestaurant . في هذه الحالة ، نحتاج إلى معرّف مطعم لمعرفة أيهما يجب تعديله. يبدو الأمر كما يلي:

@Html.ActionLink("Modifier le restaurant", "ModifierRestaurant", "Restaurant", new { id = Model.Resto.Id }, null)
الذي يولد HTML التالي:

< ;a href="/Restaurant/ModifierRestaurant/3"> ;Modifier le restaurant< ;/a> ;
تخيل أن معرف مطعم valle 3 بالطبع.
لاحظ أنه من المهم تمرير المُدخل الأخير إلى null (والتي تتوافق فعليًا مع أي سمات HTML لتمريرها ، مثل النمط) من أجل استخدام التحميل الزائد للمساعد الصحيح.
ملاحظة: إذا قمت بإنشاء ارتباط إلى إجراء لنفس وحدة التحكم ، فلا يلزم تحديده في المساعد ، فهذا تلقائي. يمكننا استبدال على سبيل المثال:

@Html.ActionLink("Modifier le restaurant", "ModifierRestaurant", "Restaurant")
بواسطة:

@Html.ActionLink("Modifier le restaurant", "ModifierRestaurant")
من اللحظة التي يقع فيها الإجراء في نفس وحدة التحكم.
سنرى في الفصل الخاص بأجهزة التحكم كيفية استرداد هذه المُدخلات ، حتى إذا كان يجب عليك بالفعل الشك في ذلك قليلاً. 
لا أستطيع وصف كل المساعدين ، سيكون مملاً ومملاً. لا تتردد في إلقاء نظرة على الإنترنت لمعرفة كيفية عملها. هذه قائمة:
مساعد الوصف
Html.ActionLink أنشئ رابطًا لطريقة (إجراء) وحدة التحكم باستخدام العلامة <a href>
Html.BeginForm إنشاء علامة نموذج <form>
Html.CheckBox إنشاء مربع اختيار <input> من النوع " checkbox "
Html.DropDownList يولد قائمة منسدلة النوع <select>, <option>
Html.Hidden إنشاء حقل مخفي <input> من النوع " hidden "
Html.ListBox إنشاء قائمة منسدلة متعددة الأنواع من الأنواع <select> ، <option>
Html.Password إنشاء مربع نص لإدخال كلمة مرور <input> من النوع " password "
Html.RadioButton يخلق زر الاختيار مع علامة <input> مثل " radio "
Html.RouteLink يفعل نفس الشيء Html.ActionLink باستثناء أنه يستخدم مسار إدخال
Html.TextArea يولد مربع نص قابل للتحرير على عدة أسطر مع العلامة <textarea>
Html.TextBox إنشاء منطقة نص قابلة للتحرير في سطر واحد باستخدام علامة <input> النوع " text "
هذه هي القائمة:
مساعد الوصف
Url.Action قم بإنشاء عنوان URL باستخدام آلية التوجيه
Url.Content إنشاء عنوان URL مطلق من عنوان URL نسبي
Url.RouteUrl يفعل نفس الشيء Url.Action باستثناء أنه يستخدم مسار إدخال
وبالمثل ، هناك مساعدين من Ajax سنستخدمهم في الفصل المخصص.
لم أقدم لك كل هؤلاء المساعدين لكم بالتفصيل ، لكن اطمئنوا ، سنرى بعضهم في العمل في فصول لاحقة.
هل من الأفضل استخدام مساعدي HTML أو كتابة HTML مباشرة عن طريق مزجه مع C#؟
هذا سؤال مهم يجب طرحه. بشكل عام ، من الحكمة استخدام المساعدين لأنهم ينشئون كودًا جيدًا. يمكنهم أيضًا إنشاء الكثير من السمات الإضافية التي سيتم استخدامها للتحقق من الصحة ، والتي سأقدمها بعد ذلك بقليل. ومع ذلك ، إذا لم تكن جميع هذه السمات ضرورية ، يمكنك استخدام خطك اليدوي لتقليل طبع لغة HTML بشكل طفيف. ومع ذلك ، فإن الحالة الأخيرة نادرة ؛ يفضلون عموما استخدام المساعدين.

واجهات العرض الجزئية


إذا كنت بحاجة إلى إعادة استخدام أجزاء من طرق العرض في أماكن متعددة ، فستكون طرق العرض الجزئية لك. على سبيل المثال ، تخيل أننا بحاجة إلى نموذج تسجيل الدخول على موقعنا. يمكننا أن نتصور إنشاء طريقة عرض تحتوي على تسميات ومربعات نصية وزر إرسال. كل شيء لطيف للغاية مع CSS وكل ما يسير على ما يرام. ولكن إذا كان علينا وضع هذا النموذج على صفحات أخرى من الموقع ، فسنضطر إلى إعادة هذا النموذج مرة أخرى ، نسخ ولصق طويل الأمد ...
الحل: واجهة عرض جزئية.
تأتي طرق العرض الجزئية مع مساعد يقوم بإرجاع طريقة عرض كسلسلة. وبالتالي يمكن استخدام هذه السلسلة داخل عرض آخر لإنتاج HTML متكرر.
دعونا ننشئ على سبيل المثال طريقة عرض جديدة في الدليل الفرعي الرئيسي ، مع الزر الأيمن المفضل لدينا ، إضافة -> طريقة العرض. في النافذة التي تفتح ، لدينا مربع اختيار يسمح لنا بإنشاء عرض جزئي:
ASP.NET framework
إضافة عرض جزئي
دعونا نسميها اتصال. ينشئ Visual Studio طريقة عرض لنا ولكن هذه المرة فارغة. على أي حال ، لا توجد علامات أساسية لصفحة HTML . في الواقع ، إنها ليست صفحة ، ولكنها جزء من الصفحة. فجأة ، يجب ألا تحتوي على علامات <html>   أو <body> ...
على سبيل المثال ، لن نقوم بعمل عرض جزئي معقد للغاية. سيكون ببساطة:

@using (Html.BeginForm())
{
    <fieldset>
        <legend>Connexion :</legend>
        @Html.Label("Login")
        @Html.TextBox("login")
        <br />

        @Html.Label("Mot de passe")
        @Html.TextBox("mdp")
        <br />
        <input type="submit" value="Se connecter..." />
    </fieldset>
}
واستخدامها؟ سهل جدا. ما عليك سوى استخدام المساعد Html.Partial الذي يُرجع سلسلة أحرف تمثل HTML . سيكون عرض الفهرس الخاص بنا:

< ;div> ;Je suis la vue index< ;/div> ;
@Html.Partial("Connexion")
Html.Partial  يسمح بوصف HTML بفضل علامة @ في البرنامج النصي. هناك أيضًا المساعد Html.RenderPartial   الذي يكتب الخلاصة مباشرة إلى الصفحة.
ماذا لو أردنا تضمين التحكم في الاتصال الخاص بنا في صفحة أخرى؟ فقط هذا السطر البسيط!
عملي أليس كذلك ؟
في الواقع ، هذا ليس صحيحًا تمامًا.  لنفترض أن هذا صحيح إذا كان العرض الجزئي موجودًا في نفس الدليل ، ولكن سيتعين عليك إعطاء المسار إذا كان موجودًا في دليل آخر.
على سبيل المثال ، تخيل أنني أقوم بإنشاء طريقة عرض فهرس في الدليل Views\Test (مع وحدة التحكم الكلاسيكية) . لعرض طريقة عرض الاتصال الجزئي الخاصة بي ، ينبغي علي القيام بما يلي:

<div>Je suis la vue index de test</div>
@Html.Partial("../Accueil/Connexion")
أو ببساطة:

<div>Je suis la vue index de test</div>
@Html.Partial("~/Views/Accueil/Connexion.cshtml")
لاحظ استخدام ملحق الملف في الحل الثاني. وسيكون لدينا:
ASP.NET framework
شاشة عرض جزئية
كقاعدة ، سيتم وضع طرق العرض الجزئية في الدليل المشترك ، مما سيسمح للاتفاقيات بالوصول إليها بسهولة من أي مكان.
بالطبع ، من النادر جدًا عرض HTML مثل هذا. بشكل عام ، سنحتاج إلى التمكن من تمرير المُدخلات إلى هذا العرض الجزئي ، هنا لماذا لا توجد سلسلة أحرف لملء حقل تسجيل الدخول مسبقًا.
في الواقع ، يمكننا تمرير أي كائن كمُدخل لتوضيح هذا ، سأمرر نموذج عرضنا بالكامل. مجرد استخدام الزائد آخر Html.Partial  .
أولاً ، أضيف خاصية Login  إلى نموذج العرض الخاص بي:

public class AccueilViewModel
{
    [Display(Name = "Le message")]
    public string Message { get; set; }
    public DateTime Date { get; set; }
    public Models.Resto Resto { get; set; }
    public string Login { get; set; }
}
ثم ، في Index رأيي ، علي فقط تحويل المكالمة المساعدة:

<div>Je suis la vue index</div>
@Html.Partial("Connexion", Model)
وأخيرًا ، في العرض الجزئي Connexion ، يجب علي كتابة العرض بقوة:

@model  ChoixResto.ViewModels.AccueilViewModel
ثم استخدم Login خاصية نموذج العرض من العرض الجزئي:

    @Html.TextBox("login", Model.Login)
ها أنت ذا ، الآن عرض المنظر ، TextBox سيكون مملوء مسبقا.
ASP.NET framework
عرض العرض الجزئي باستخدام النموذج
لاحظ أنه من الممكن أيضًا تمرير البيانات عبر ViewBag  أو ViewData  . من لحظة إدخال كائن ما ، يبقى هناك حتى نهاية الطلب ، وبالتالي يمكن الوصول إليه من خلال طرق عرض جزئية.
لا يزال في طرق العرض الجزئية ، هناك مساعد آخر يسمح لك بإرجاع جزء صغير من الصفحة. هذا هو المساعد Html.Action   (أو مساعده Html.RenderAction  ) الذي يوفر تحكمًا أفضل وإمكانية إعادة استخدام أفضل. في الواقع ، Html.Action   تستدعي في الواقع وحدة تحكم تُرجع طريقة عرض جزئية. يوفر ذلك إمكانية تحميل الصفحة الجزئية لنموذجها في سياق مختلف.
على سبيل المثال ، Accueil  لنقم بإنشاء إجراء في وحدة التحكم يقوم بإرجاع قائمة المطاعم:

public ActionResult AfficheListeRestaurant()
{
    List<Models.Resto> listeDesRestos = new List<Resto>
    {
        new Resto { Id = 1, Nom = "Resto pinambour", Telephone = "1234" },
        new Resto { Id = 2, Nom = "Resto tologie", Telephone = "1234" },
        new Resto { Id = 5, Nom = "Resto ride", Telephone = "5678" },
        new Resto { Id = 9, Nom = "Resto toro", Telephone = "555" },
    };
    return PartialView(listeDesRestos);
}
لاحظ وجود الأسلوب PartialView  الذي يحل محل استدعاء الأسلوب View()  .
ثم قم بإنشاء عرض PosterListRestaurant ، جزئيًا بالطبع ، واكتبه مع قائمة المطاعم:

    @model  List<ChoixResto.Models.Resto>
    
    <table>
        <tr>
            <th>Nom</th>
            <th>Téléphone</th>
        </tr>
        @foreach (var resto in Model)
        {
        <tr>
            <td>@resto.Nom</td>
            <td>@resto.Telephone</td>
        </tr>
        }
    </table>
    
الآن عليك فقط تعديل العرض الرئيسي لتضمين العرض الجزئي:

    <div>Je suis la vue index</div>
     @Html.Action("AfficheListeRestaurant")
    
نقوم بتمرير المُدخل اسم إجراء وحدة التحكم الذي نريد استدعاؤه. بالطبع ، من الممكن استخدام وحدة تحكم أخرى باستخدام الأحمال الزائدة الأخرى من المساعد Html.Action  .
تعرض طريقة العرض الرئيسية واجهة عرضنا ، وتلتقي بالمساعد Html.Action  ، وتنشئ الإجراء المطلوب ؛ تقوم وحدة التحكم بإرجاع العرض الجزئي المعروض في العرض الرئيسي.
وها نحن هنا ، يظهر العرض الجزئي في عرض الفهرس الخاص بنا:
ASP.NET framework
عرض طريقة عرض جزئية من إجراء
ترى على الفور قوة هذا المساعد ... ومع ذلك ، قد ترى عيوبه ... ونعم ، لقد قمنا بإنشاء إجراء جديد في وحدة التحكم الخاصة بنا. لذلك ، منطقياً ، يمكننا استدعاؤه مباشرة عبر عنوان URL   http://localhost:60818/Accueil/afficheListeRestaurant  . لنجرب:
ASP.NET framework
عرض مباشر للعرض المرتبط بالإجراء
اذا. إنها تعمل. بالإضافة إلى ذلك ، فإن HTML لا يذهب على الإطلاق ، ويمكننا رؤيته في عنوان الصفحة ... لا يوجد. إذا نظرت إلى كود المصدر للصفحة ، يمكنك أن ترى أنها تتكون فقط من كود العرض الجزئي:

<table>
    <tr>
        <th>Nom</th>
        <th>Téléphone</th>
    </tr>
    <tr>
        <td>Resto pinambour</td>
        <td>1234</td>
    </tr>
    <tr>
        <td>Resto tologie</td>
        <td>1234</td>
    </tr>
    <tr>
        <td>Resto ride</td>
        <td>5678</td>
    </tr>
    <tr>
        <td>Resto toro</td>
        <td>555</td>
    </tr>
</table>
لا علامة <html>, <body>  ، لا شيء ... وهو غير صحيح على الإطلاق.
لا يمكننا فقط استدعاء هذا العرض عندما لا أريد بالضرورة أن يكون قابلاً للعرض بدون طريقة العرض الرئيسية ، ولكن بالإضافة إلى ذلك ، فإنه ينتج HTML سيئًا.
لحسن الحظ ، يمكن لـ ASP.NET MVC معالجة هذا النوع من المواقف. من الأفضل ، وإلا سيكون الأمر سخيفًا بعض الشيء كإطار ... يمكننا وضع علامة على طريقة وحدة التحكم الخاصة بنا على أنها قابلة للاستدعاء فقط من واجهة العرض الأم ، وهذا يعني أنه من واجهة العرض الابن . فقط استخدم سمة:

 [ChildActionOnly]
public ActionResult AfficheListeRestaurant()
{
    List<Models.Resto> listeDesRestos = new List<Resto>
    {
        new Resto { Id = 1, Nom = "Resto pinambour", Telephone = "1234" },
        new Resto { Id = 2, Nom = "Resto tologie", Telephone = "1234" },
        new Resto { Id = 5, Nom = "Resto ride", Telephone = "5678" },
        new Resto { Id = 9, Nom = "Resto toro", Telephone = "555" },
    };
    return PartialView(listeDesRestos);
}
والآن ، عندما نحاول استدعاء الإجراء مباشرة ، نحصل على خطأ:
ASP.NET framework
حدث خطأ عند عرض طريقة العرض الفرعية
وهو الهدف ، أنه لا يمكن الوصول إلى الإجراء إلا بطلب الابن.
واحد آخر شيء مع إطلالة جزئية ... إذا كنت غريبة، قد يكون لديك لتحل محل اختبار PartialView  من قبل View  وكان لديك تقارير أنه لم يتغير أي شيء. View()  يمكن عرض العرض عادي بشكل جيد ، ولكن أيضًا عرض جزئي. والعكس صحيح ، PartialView()   يمكن عرض العرض عادي بشكل جزئي كعرض جزئي . ويتناسب عكسيا!
في الواقع ، هو محرك العرض الذي يقرر كيفية التعامل مع طرق العرض الجزئية وطرق العرض العادية. هنا ، النتيجة هي نفسها ، ولكن قد لا يكون الأمر كذلك دائمًا ...
على أي حال ، ليس من الجيد الاعتماد عليها. في كلتا الحالتين ، من الجيد استخدام طرق عرض جزئية وطرق مرتبطة بها عندما تكون حقًا. بالفعل ، إنه صحيح دلالة ، بالإضافة إلى أنه سيسمح للمطورين الآخرين (أو لاحقًا) برؤية ما هو جزئي ، وبالتالي يمكن إعادة استخدامه ، لما هو "طبيعي" .

التشفير والأمن


إذا كنت تتذكر قبل ذلك بقليل ، فقد رأينا أن المساعدين التاليين:

<div>Je suis la vue index</div>
@Html.Label("estMajeur", "Cochez la case si vous êtes majeur")
@Html.CheckBox("estMajeur", true)
<input type="submit" value="Envoyer" />
أنتجت HTML التالي:

<label for="estMajeur">Cochez la case si vous êtes majeur</label>
<input checked="checked" id="estMajeur" name="estMajeur" type="checkbox" value="true" /><input name="estMajeur" type="hidden" value="false" />
<input type="submit" value="Envoyer" />
وعلى وجه الخصوص ، تم ترميز ê منكم في HTML جيد. في الواقع ، هذا جزء من آلية ترميز أكثر عمومية يحتاج أي مطور HTML جيد إلى إتقانها.
على سبيل المثال ، كيف سيبدو الرمز التالي؟

@Html.Label("estMajeur", "Cochez la case si vous êtes majeur")
ربما نأمل أن تصبح الكلمة الرئيسية جريئة بفضل علامة HTML <strong> ؟ لا ، يتم ترميز الأحرف <and> ويتم عرضها بتنسيق HTML كما يلي:

<label for="estMajeur">Cochez la case si vous êtes <strong>majeur</strong></label>
وهذا أفضل بكثير. لأنه هنا ، كل شيء على ما يرام لأنه أنا الذي يكتب مباشرة كود واجهة العرض (وأنا أثق في الكود الخاص بي!) ، ولكن ماذا سيحدث إذا عرضت نتيجة إدخال مباشرة مستخدم أو معلومات قادمة من خدمة ويب أو قاعدة بيانات لا أتحكم فيها؟ حسنًا ، أنت تشك في النتيجة ... لا مزيد من التحكم في عرض صفحة الويب ، وهذا يعني ضمنيًا إمكانية جعل موقعك عرضة للهجوم.
وهذا هو آخر شيء نريده حقًا!
لحسن الحظ ، فكرنا في ASP.NET MVC ومحرك عرض Razor الخاص به يقوم تلقائيًا بترميز كل شيء يتم عرضه افتراضيًا. خذ وحدة التحكم التالية:

public ActionResult Index()
{
    AccueilViewModel vm = new AccueilViewModel
    {
        Message = "Bonjour depuis le <span style=\"color:red\">contrôleur</span>"
    };
    return View(vm);
}
عرض الرسالة في العرض بفضل:

<div>
  @Model.Message
</div>
سينتج HTML التالي:

<div>
    Bonjour depuis le <span style="color:red">contrôleur</span>
</div>
وبالتالي ، لا يمكن عرض كلمة تحكم باللون الأحمر ، لأننا قد نميل إلى التخيل. وهو في النهاية شيء جيد ، لأن لدينا حلول أخرى للقيام بذلك. هذا يحمينا من جزء كبير من الثغرات الأمنية.
ومع ذلك ، لا يزال هناك إمكانية لتجاوز هذا الترميز التلقائي. تخيل أننا نريد عرض HTML مباشرة وأننا على يقين من مصدره أو تنسيقه. يمكن أن يكون من السهل جدًا تخزين HTML مباشرة في قاعدة البيانات. لذلك إذا كنت تستخدم أداة لإنشاء HTML لإعلان banner الخاص بك أو ببساطة CMS ، يتم تخزين HTML في قاعدة البيانات ويمكن عرضه مباشرة عند عرض العرض. بسيطة وفعالة.
للقيام بذلك ، يمكننا استخدام المساعد Html.Raw  :

<div>Je suis la vue index</div>
<ul>
    <li>@Html.Raw(Model.Message)</li>
    <li>@Model.Message</li>
</ul>
وسوف نحصل على النتيجة التالية:
ASP.NET framework
HTML مع ترميز وبدون
عملي إلى حد ما 
ولكن احذر ، تذكر أن عرض HTML يمكن أن يجعل موقعك عرضة للهجوم ، خاصة إذا كان ما تريد عرضه يعتمد على إدخال المستخدم.
لا يجب أن تثق بمستخدم أبدًا.
سنعود إلى قصص الأمان هذه بعد ذلك بقليل عندما تعلمنا كيفية معالجة البيانات التي أدخلها المستخدم. ومع ذلك ، يمكنك تذكر هذا:
يفضل بشكل عام استخدام @ بدلاً من Html.Raw   ترميز الأحرف الخاصة تلقائيًا والحماية من الهجمات المحتملة ؛ ما لم تكن بحاجة إليها صراحة وتثق في ما تريد عرضه.

باختصار


  • تسمح لك المشاهدات بعرض HTML الذي سيراه المستخدم في متصفحه.
  • يمكنك مزج HTML و C# في طريقة عرض باستخدام الحرف @ .
  • من الممكن كتابة طريقة عرض بحيث تكون خاصية النموذج معروفة وأن تستفيد طريقة العرض من الإكمال التلقائي.
  • هناك عدد كبير من مساعد HTML الذي يهدف إلى تبسيط إنشاء علامات تحكم HTML بالنسبة لنا
  • يمكن أن تكون المشاهدات جزئية أيضًا بحيث يمكن عرض إحدى نهايات الصفحة في أخرى
  • يقوم ASP.NET MVC بترميز الأحرف تلقائيًا للحد من مخاطر اختراق الأمان