اذهب إلى المحتوى
  • 0

كيف نحدّث ICollection في ASP.NET MVC Razor؟

horizon

السؤال

السلام عليكم و رحمة الله و بركاته
لنقل أن لدي ViewModel احد خصائصه من نوع تجميعة (ICollection) من عدد من العناصر ، لنقل أن العنصر من الكلاس أدناه
 

class MyClass
{
  public int Id {get; set;}
  public string Name {get; set;}
}

أريد أن اعدل هذه التجميعة في المتصفح و أن أرسلها للسيرفر.
حتى لو لم أقم بتعديل هذه التجميعة ، عندما أرسلها إلى السيرفر ستكون قيمتها null ، و هذا يخرب كل شيء.
كيف اجعل الـController يستقبل قيمة التجميعة بدل قيمة null؟

رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 1

يمكنك ذلك بالطبع، لقد كتبت لك مثالًا بسيطًا يرشدك لهذا الأمر. أجريت الفرضيّات التالية عند كتابتي لهذا المثال:

1- الصنف Student يحتوي على خاصيتين Id و Name.

2- الصنف School يحتوي على خاصيتين أيضًا: Name و Students. حيث أنّ الخاصية Students من النوع IList<Student>. انظر إلى الشيفرة التالية:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}
using System.Collections.Generic;

public class School
{
    public IList<Student> Students { get; set; }

    public string Name { get; set; }
}

أنشئ مشروعًا جديدًا من نوع ASP.NET MVC ، وأضف إليه الصنفين السابقين (كل صنف بملف مستقل) ضمن المجلد Models. ثم اذهب إلى المتحكم IndexController وعدّل الأكشن Index ليكون على الشكل التالي:

public ActionResult Index(School school)
{
    if (school.Students == null)
    {
        school.Students = new List<Student>();
    }

    return View(school);
}

وإليك الآن ملف العرض Index.cshtml:

@model ModelBinding.Models.School

@{
    ViewBag.Title = "Home Page";
}

@if (Model.Students.Count() == 0)
{
    using (Html.BeginForm())
    {
        <div class="form-group">
            <h3>School Name</h3>
            @Html.TextBoxFor(m => m.Name, new {@class = "form-control", autofocus = "autofocus"})
        </div>
        <hr/>
        for (int i = 0; i < 3; i++)
        {
            <div class="form-group">
                <h4>Student @(i + 1)</h4>
                <label>Id</label>
                @Html.Editor("Students[" + i + "].Id")
                <label>Name</label>
                @Html.Editor("Students[" + i + "].Name")
            </div>
        }
        
        <button type="submit" class="btn btn-primary">Save</button>
    }
}
else
{
    <h1>@Model.Name</h1>
    foreach (var student in Model.Students)
    {
        <p>@student.Id, @student.Name</p>
    }
    @Html.ActionLink("Back", "Index");
}

نفّذ البرنامج وانتقل إلى Home/Index من المتصفّح، سيعرض إليك حقولًا فارغة لتعبّئها (افترضت أنّ هنا 3 طلاب فقط سيتم تعبئة البيانات لهم)، وبعد نقر Save ستُرسل البيانات إلى الأكشن Index ليفهمها ويعرضها لك مرّة أخرى. يمكنك تنفيذ البرنامج بوضع التنقيح وتنفيذه خطوة بخطوة لتفهم ما يجري بالضبط.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0
بتاريخ 2 ساعات قال حسام برهان:

يمكنك ذلك بالطبع، لقد كتبت لك مثالًا بسيطًا يرشدك لهذا الأمر. أجريت الفرضيّات التالية عند كتابتي لهذا المثال:

1- الصنف Student يحتوي على خاصيتين Id و Name.

2- الصنف School يحتوي على خاصيتين أيضًا: Name و Students. حيث أنّ الخاصية Students من النوع IList<Student>. انظر إلى الشيفرة التالية:


public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
}

using System.Collections.Generic;

public class School
{
    public IList<Student> Students { get; set; }

    public string Name { get; set; }
}

أنشئ مشروعًا جديدًا من نوع ASP.NET MVC ، وأضف إليه الصنفين السابقين (كل صنف بملف مستقل) ضمن المجلد Models. ثم اذهب إلى المتحكم IndexController وعدّل الأكشن Index ليكون على الشكل التالي:


public ActionResult Index(School school)
{
    if (school.Students == null)
    {
        school.Students = new List<Student>();
    }

    return View(school);
}

وإليك الآن ملف العرض Index.cshtml:


@model ModelBinding.Models.School

@{
    ViewBag.Title = "Home Page";
}

@if (Model.Students.Count() == 0)
{
    using (Html.BeginForm())
    {
        <div class="form-group">
            <h3>School Name</h3>
            @Html.TextBoxFor(m => m.Name, new {@class = "form-control", autofocus = "autofocus"})
        </div>
        <hr/>
        for (int i = 0; i < 3; i++)
        {
            <div class="form-group">
                <h4>Student @(i + 1)</h4>
                <label>Id</label>
                @Html.Editor("Students[" + i + "].Id")
                <label>Name</label>
                @Html.Editor("Students[" + i + "].Name")
            </div>
        }
        
        <button type="submit" class="btn btn-primary">Save</button>
    }
}
else
{
    <h1>@Model.Name</h1>
    foreach (var student in Model.Students)
    {
        <p>@student.Id, @student.Name</p>
    }
    @Html.ActionLink("Back", "Index");
}

نفّذ البرنامج وانتقل إلى Home/Index من المتصفّح، سيعرض إليك حقولًا فارغة لتعبّئها (افترضت أنّ هنا 3 طلاب فقط سيتم تعبئة البيانات لهم)، وبعد نقر Save ستُرسل البيانات إلى الأكشن Index ليفهمها ويعرضها لك مرّة أخرى. يمكنك تنفيذ البرنامج بوضع التنقيح وتنفيذه خطوة بخطوة لتفهم ما يجري بالضبط.

إذن لا توجد طريقة إلا بالتغيير الى IList.

اعتقد ان هذا سيعمل لمرة واحدة فقط ، و اذا جربنا على Model فيه مجموعة من الطلاب ستظهر نفس المشكلة.

رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 0

بالنسبة ل ICollection اتصور انها ستعمل. جرب ذلك.

أما أنها ستعمل لمرة واحدة فهذا لم أفهمه!

إذا كان لديك مشكلة محددة فأرجو توضيحها مع إرفاق الكود

رابط هذا التعليق
شارك على الشبكات الإجتماعية

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...