مفاهيم متقدمه في Model Binding في ASP.NET Core

-

بنتعلم في هذا الدرس مفاهيم ومواضيع متقدمه حول تقنية Model Binding في ASP.NET Core ، حيث سنغطي بعض الميزات المتقدمة والقوية لهذه التقنية.

تمام نبدأ 

Model Binding to Arrays

يمكنك عمل Model Binding ل array of parameters. ولتوضيح هذه الميزة ، خلونا نبدأ بإنشاء action method تسمى Places  في وحدة Home controller  كما هو موضح في الكود الوارد أدناه:

public IActionResult Places(string[] places) => View(places);
تمام نفهم هذا action. 
اضفنا parameter في هذا action من نوع string array باسم places. تعمل هنا ميزة model binding على البحث عن العنصر المسمى places في 
(form data values, routing variables ,query strings) وإنشاء مصفوفة تحتوي على هذه القيم.
نعمل View لعرض القيم في Home وبنضيف الكود التالي:

@model string[] @{     Layout = "_Layout";     ViewData["Title"] = "Places"; } <h2>Places</h2> @if (Model.Length == 0) {     <form asp-action="Places" method="post">             <div class="form-group">                 <label>Add New Place </label>                 <input id="places" name="places" class="form-control" />             </div>         <button type="submit" class="btn btn-primary">Submit</button>     </form> } else {     <table class="table table-sm table-bordered table-  striped">        @foreach (string place in Model)         {             <tr><th>Place:</th><td>@place</td></tr>         }     </table> }
طيب نفهم شو عملنا. 
اضفنا الأمر
@if (Model.Length == 0) 
بهدف التحقق مما إذا كان model فارغًا أم لا. إذا لم يكن النموذج فارغًا ، فسيتم عرض الأماكن places  الموجوده في model object باستخدام foreach. وفي حال كان النموذج فارغًا ، فسيتم إضافة 3 أماكن في 3<input> لها نفس id بقيمة places والاسم ايضا باسم places.

تمام نشغل الصفحة ونشوف النتيجة.
https://localhost:44382/home/places

تم انشاء input element في الصفحة وكلها متطابقة لها نفس الاسم وهذا الاسم هو نفس اسم parameter في  action method الي هو places. لذلك عندما يتم إرسال النموذج ، فإن ميزة Model Binding سوف تستخرج قيم جميع العناصر التي لها أسماء places وبعدها بتعمل على إنشاء مصفوفة تحتوي على هذه القيم. ثم يتم تمرير المصفوفة فيparameter  إلى action method.

اذا حاولنا نشوف source الخاص بالصفحة بنشوف النتيجة :


لاحظ ان كل input element لها نفس id ونفس name، الي هو نفس parameter الموجود في action.
الان المطلوب نجرب نعبي هذه الحقول ونعمل submit ونشوف النتيجة.

نعمل breakpoint في action وشوف النتيجة. اكيد الاماكن الي دخلناها في الصفحة بتظهر في action. 



استخدام Collection مع Model Binding 

يمكن تطبيق Model binding كمان على Collection.
تمام وحتي نفهم الموضوع خلونا نعدل الكود السابق:

public IActionResult Places(List<string> places) => View(places);
عملنا في هذا الكود تغيير ل places تحويل من array الى  List. 

تمام الان نعدل على View الى :

@model List<string>
@{
    Layout = "_Layout";
    ViewData["Title"] = "Places";
}
<h2>Places</h2>
@if (Model.Count == 0)
{
    <form asp-action="Places" method="post">
        @for (int i = 1; i <= 3; i++)
        {
            <div class="form-group">
                <label>Place @i:</label>
                <input id="places" name="places" class="form-control" />
            </div>
        }
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
}
else
{
    <table class="table table-sm table-bordered table-striped">
        @foreach (string place in Model)
        {
            <tr><th>Place:</th><td>@place</td></tr>
        }
    </table>
}
استقبلنا هون Model من نوع List وتحققنا من وجود بيانات باستخدام الكود:
@if (Model.Count == 0)
الان جرب شغل الصفحة وشوف النتيجة. اكيد بتكون النتيجة نفس النتيجة السابقة لكن الفرق هون استخدمنا Collection. 


استخدام Collection في Model Binding مع الاناع المعقده Complex Types

من اناع Model Binding ايضا استخدام Collection مع اناع معقده، بحيث بنستخدم Model كامل لارسال واستقبال البيانات. 
تمام وحتي نفهم شو المقصود وكيف التنفيذ نبدا بانشاء class باسم  StudnetAddress في مجلد Model ونضيف الكود التالي: 
  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace StudentsAcademy.Models
{
    public class StudnetAddress
    {
        public string City { get; set; }
        public string Country { get; set; }
        public string Street { get; set; }
    }
}
انشاء Controller 
 
تمام الان نرجع ل Home Controller  ونضيف action جديد باسم StudnetAddress

public IActionResult StudnetAddress(List<StudnetAddress> studnetaddress) => View(studnetaddress);

انشاء View 
الان المطلوب نعمل view باسم studnetaddress داخل مجلد Views ➤ Home  بالنقر يمن فوق action السابق وبعدها بنختار Add New View واضف الكود التالي :

@model List<StudnetAddress>
@{
    Layout = "_Layout";
    ViewData["Title"] = "StudnetAddress";
}
<h2>Address</h2>
@if (Model.Count() == 0)
{
    <form asp-action="StudnetAddress" method="post">
        @for (int i = 0; i < 3; i++)
        {
        <fieldset class="form-group">
            <legend>Address @(i + 1)</legend>
            <div class="form-group">
                <div class="row">
                    <div class="col-1"><label>City:</label></div>
                    <div class="col-2"><input name="[@i].City" class="form-control" /></div>
                    <div class="col-1"><label>Country:</label></div>
                    <div class="col-2"><input name="[@i].Country" class="form-control" /></div>
                    <div class="col-1">  <label>Street:</label></div>
                    <div class="col-2"> <input name="[@i].Street" class="form-control" /></div>
                </div>
                </div>
</fieldset>
        }
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
}
else
{
    <table class="table table-sm table-bordered table-striped">
        <tr><th>City</th><th>Country</th><th>Street</th></tr>
        @foreach (var address in Model)
        {
            <tr><td>@address.City</td><td>@address.Country</td><td>@address.Street</td></tr>
        }
    </table>
}
تمام مثل ما عملنا سابقا، لكن الفرق ان في هذا View استقبلنا List من نوع Model الكود:
@model List<StudnetAddress>
شغل الصفحة 
https://localhost:44382/home/StudnetAddress
دخل بيانات في الحقول المطلوبة 
وبعدها انقر فوق Submit 
وشوف النتيجة :
وطبقنا هاي الفكره سابقا في ADO.NET باستخدام بيانات حقيقه.