-3

I get an error because of new features I recently added to my project, so now other features aren't working any more.

I am working with theses files :

Project.cs :

using System;
using System.Collections.Generic;
using System.Web.Mvc;

namespace ProjetJB2.Models
{
public class Project
{
    public int Id { get; set; }
    public String Name { get; set; }
    public String Description { get; set; }
    public Nullable<int> TeacherId { get; set; } 
    public virtual Teacher Teacher { get; set; }
    public DateTime BeginDate { get; set; }
    public DateTime EndDate { get; set; }
    //public String Controller { get; set; }
}
}

ProjectController.cs :

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using ProjetJB2.Models;

namespace ProjetJB2.Controllers
{
public class ProjectController : Controller
{
    private ProjetJB2Context db = new ProjetJB2Context();

    public ViewResult Index (String searchString)
    {
        var projects = from p in db.Projects
                       select p;
        if (!String.IsNullOrEmpty(searchString))
        {
            projects = projects.Where(p => p.Name.Contains(searchString) || p.Description.Contains(searchString));
        }
        return View(projects.ToList());
    }

    // GET: Project/Details/5
    public async Task<ActionResult> Details(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Project project = await db.Projects.FindAsync(id);
        if (project == null)
        {
            return HttpNotFound();
        }
        return View(project);
    }

    // GET: Project/Create
    public ActionResult Create()
    {
        ViewBag.TeacherId = new SelectList(db.Teachers, "Id", "LastName");
        return View();
    }

    // POST: Project/Create
    // Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour 
    // plus de détails, voir  https://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Create([Bind(Include = "Id,Name,Description,TeacherId,BeginDate,EndDate")] Project project)
    {
        if (ModelState.IsValid)
        {
            db.Projects.Add(project);
            await db.SaveChangesAsync();
            return RedirectToAction("Index");
        }

        ViewBag.TeacherId = new SelectList(db.Teachers, "Id", "LastName", project.TeacherId);
        return View(project);
    }

    // GET: Project/Edit/5
    public async Task<ActionResult> Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        Project project = await db.Projects.FindAsync(id);

        if (project == null)
        {
            return HttpNotFound();
        }

        ViewBag.TeacherId = new SelectList(db.Teachers, "Id", "LastName", project.TeacherId);
        return View(project);
    }

    // POST: Project/Edit/5
    // Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour 
    // plus de détails, voir  https://go.microsoft.com/fwlink/?LinkId=317598.
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit([Bind(Include = "Id,Name,Description,TeacherId,BeginDate,EndDate")] Project project)
    {
        if (ModelState.IsValid)
        {
            db.Entry(project).State = EntityState.Modified;
            await db.SaveChangesAsync();
            return RedirectToAction("Index");
        }

        ViewBag.TeacherId = new SelectList(db.Teachers, "Id", "LastName", project.TeacherId);
        return View(project);
    }

    //public virtual ActionResult MyAction()

    // GET: Project/Delete/5
    public async Task<ActionResult> Delete(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        Project project = await db.Projects.FindAsync(id);

        if (project == null)
        {
            return HttpNotFound();
        }

        return View(project);
    }

    // POST: Project/Delete/5
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> DeleteConfirmed(int id)
    {
        Project project = await db.Projects.FindAsync(id);
        db.Projects.Remove(project);
        await db.SaveChangesAsync();
        return RedirectToAction("Index");
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }

        base.Dispose(disposing);
    }
}
}

And I will use the two following views to explain the problem :

Project/Index.cshtml :

@model IEnumerable <ProjetJB2.Models.Project>

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>
<p>@Html.ActionLink("Create New", "Create")</p>
<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.Teacher.LastName)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Name)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Description)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.BeginDate)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.EndDate)
    </th>
    <th></th>
</tr>
@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Teacher.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.BeginDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EndDate)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
            @Html.ActionLink("Details", "Details", new { id = item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id = item.Id })
        </td>
    </tr>
}
</table>

Project/Edit.cshtml :

@model ProjetJB2.Models.Project

@{
ViewBag.Title = "Details";
}

<h2>Details</h2>

<div>
<h4>Project</h4>
<hr />
<dl class="dl-horizontal">
    <dt>
        @Html.DisplayNameFor(model => model.Teacher.LastName)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.Teacher.LastName)
    </dd>

    <dt>
        @Html.DisplayNameFor(model => model.Name)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.Name)
    </dd>

    <dt>
        @Html.DisplayNameFor(model => model.Description)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.Description)
    </dd>

    <dt>
        @Html.DisplayNameFor(model => model.BeginDate)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.BeginDate)
    </dd>

    <dt>
        @Html.DisplayNameFor(model => model.EndDate)
    </dt>

    <dd>
        @Html.DisplayFor(model => model.EndDate)
    </dd>

</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
@Html.ActionLink("Back to List", "Index")
</p>

So as I said I made some changes to make new features work, the mainly one is that I changed this code line (which is the first code line in all of my views) :

 @model ProjetJB2.Models.Project

into this code line :

@model IEnumerable <ProjetJB2.Models.Project>

so the line :

 @foreach (var item in Model)

could work. This is an example, and is possibly the main source of my problem (I might have also done others changes elsewhere but it will be long to state them).

My Project/Index view is working as I want but the Project/Details isn't working anymore (I believe it used to work fine before I did the changes). Now when I try to reach the Details view I get this error:

The model item passed into the dictionary is of type «System.Data.Entity.DynamicProxies.Project_244C81CDE2ECC6523E9086FDD0B242D6B81E39F8C4CBE2EA00B9EE0E7D21B0C4 » but this dictionary requires a model item of type « System.Collections.Generic.IEnumerable`1[ProjetJB2.Models.Project] »

And when I change it, I get a lot of red underlined code. What should I do ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
cineciine
  • 1
  • 1
  • 1) Make sure your controller is sending an `IEnumerable` to the view if you changed it to `IEnumerable` in your view. 2) Do not use `foreach` in your view. Why? See [this](https://stackoverflow.com/a/48357541/4228458) and make sure to read it carefully and understand it. – CodingYoshi Jun 03 '18 at 15:31
  • The error is clear about the issue: The thing which is passed to the view from the controller is `Project` but the view is expecting `IEnumerable`. – CodingYoshi Jun 03 '18 at 15:34

1 Answers1

0

So as I said I made some changes to make new features work, the mainly one is that I changed this code line (which is the first code line in all of my views) :

@model ProjetJB2.Models.Project into @model IEnumerable<ProjetJB2.Models.Project>

That's exactly the problem. The Index view, which lists multiple items, is OK with this change. However, when you create/detail/edit, you do so for a specific item, not multiple at the same time.

As you can see here:

public async Task<ActionResult> Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Project project = await db.Projects.FindAsync(id);
    if (project == null)
    {
        return HttpNotFound();
    }

    // returning a single item, not a collection
    return View(project);
}
Camilo Terevinto
  • 31,141
  • 6
  • 88
  • 120