1

This is my first MVC project and I'm trying to understand how each component works with the other. I am building a basic school system (courses, students, and enrollments).

In my main view (Calculus.cshtml), I am displaying the course name and description (working properly) from my CourseController. Now, I want to use a partial view (_studentList) to display a list of students that are enrolled in the course from a controller called StudentController.

I tried a couple of different things:

First I just used the function in my controller to pass the List<Student> to the partial view like so:

public async Task<IActionResult> StudentList(int id)
{
        List<Student> StudentList = await _context.Student
                      .Include(s => s.Course)
                      .AsNoTracking()
                      .Where(x => x.Course.ID == id)
                      .ToListAsync();

        return PartialView("_StudentList", StudentList);
}

(I also want to mention my List is populating correctly, it's simply getting this list to the view so I can display the contents).

Calculus.cshtml

@model SchoolSystem.Models.Course

<div>
    <h4>Calculus</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.CourseDescription)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.CourseDescription)
        </dd>
    </dl>
</div>

<dd class="col-sm-10">
    <partial name="_StudentList" />

</dd>

_StudentList.cshtml

@model SchoolSystem.Models.Student

<table class="table">
    <tr>
        <th>Student Name</th>
        <th>StudentDOB</th>
        <th>StudentPhoneNum</th>
        <th>StudentPhoneNum</th>

    </tr>
    @foreach (var student in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => student.StudentName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.StudentDOB)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.StudentPhoneNum)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.studentAddress)
            </td>
        </tr>
    }
</table>

However, when I try this I get an error saying:

The model item passed into the dictionary is of type 'SchoolSystem.Models.Course', but this dictionary requires a model item of type 'SchoolSystem.Models.Student'

I was then reading about view models and tried to make one but I still don't know how to use a different model in the partial view. Is that even possible?

In my StudentList() function, I am returning a parameter to the partial view - how would I use that?

return PartialView("_StudentList", StudentList);

Student.cs Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;

namespace SchoolSystem.Models
{
    public class Student
    {
        public int ID { get; set; }

        [Display(Name = "Student Name")]
        public string StudentName { get; set; }

        [Display(Name = "Student Date of Birth")]
        public string StudentDOB { get; set; }

        [Display(Name = "Student Phone Number")]
        public string StudentPhoneNum { get; set; }

        [Display(Name = "Student Address")]
        public string studentAddress { get; set; }
        public virtual Course Course { get; set; }
    }
}

Sorry for all the questions, I'm just trying to understand how to get my program working right.

7
  • If you want to render the partial view from another main view you need to pass the model object to the view from the main view itself. <partial name="_StudentList" /> will pass the model object of the main view to the partial view. And it does not match with partial view model type, that's why you are getting this error. Commented Dec 3, 2020 at 4:16
  • What is your model design?Could you share with us? Commented Dec 3, 2020 at 4:21
  • @ChetanRanpariya I see what you're saying, like: @Html.Partial("_StudentList", myModel)? The thing is, my main view is using a different model (Model.course) and I need model.student. So how do I pass model.student to the partial view? Commented Dec 3, 2020 at 4:21
  • You need to use @Html.RenderAction("StudentList", Model.StudentId) this will call the controller action and return the partial view. You also need to change model type to @model List<SchoolSystem.Models.Student> in _StudentList.cshtml Commented Dec 3, 2020 at 4:23
  • @rena I added the student model ^ Commented Dec 3, 2020 at 4:23

1 Answer 1

3

For your partial view have a foreach loop,your partial view is expecting a model of type IEnumerable<Student>.And the easier way is to return view with course model and student model if they have relationships,no need to specify a method to return partial view.

Here is a working demo:

Model:

public class Student
{
    public int ID { get; set; }

    [Display(Name = "Student Name")]
    public string StudentName { get; set; }

    [Display(Name = "Student Date of Birth")]
    public string StudentDOB { get; set; }

    [Display(Name = "Student Phone Number")]
    public string StudentPhoneNum { get; set; }

    [Display(Name = "Student Address")]
    public string studentAddress { get; set; }
    public virtual Course Course { get; set; }
}
public class Course
{
    public int ID { get; set; }
    public string CourseDescription { get; set; }
    public List<Student> Students { get; set; }
}

View(Calculus.cshtml):

@model Course

<div>
    <h4>Calculus</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-5">
            @Html.DisplayNameFor(model => model.CourseDescription)
        </dt>
        <dd class="col-sm-5">
            @Html.DisplayFor(model => model.CourseDescription)
        </dd>
    </dl>
</div>

<dd class="col-sm-10">
    <partial name="_StudentList" model="Model.Students" />   //change here....

</dd>

Partial View:

@model IEnumerable<Student>   //change here....

<table class="table">
    <tr>
        <th>Student Name</th>
        <th>StudentDOB</th>
        <th>StudentPhoneNum</th>
        <th>StudentPhoneNum</th>

    </tr>
    @foreach (var student in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => student.StudentName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.StudentDOB)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.StudentPhoneNum)
            </td>
            <td>
                @Html.DisplayFor(modelItem => student.studentAddress)
            </td>
        </tr>
    }
</table>

Controller:

//GET:Home/Calculus/5
public async Task<IActionResult> Calculus(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var model = await _context.Course.Include(s=>s.Students)
        .FirstOrDefaultAsync(m => m.ID == id);
    return View(model);
}

Result: enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.