I'm trying to print out data from an SQL query, but I'm running into error after error.
Bassically what Im trying to do is fetch some data from teachers out of a database, and then make a list of them on my view. However everytime I try to print, I get this error
ViewModel' does not contain a definition for 'FirstName' and no extension method 'FirstName' accepting a first argument of type 'ViewModel' could be found.
Here's my code;
ViewModel
namespace Ability.Models
{
public class ViewModel
{
public virtual IEnumerable<Teacher> Teachers { get; set; }
public Teacher Teacher { get; set; }
public virtual IEnumerable<Skill> Skills { get; set; }
public Skill Skill { get; set; }
}
}
Controller
public ActionResult Index()
{
string campus = Request.Params["Campus"];
if (campus != null)
{
if (campus == "Alle")
{
var teachers = (from t in db.Teachers
select t);
}
else
{
var teachers = (from t in db.Teachers
where t.Campus == campus
select t );
}
}
else
{
var teachers = (from t in db.Teachers
select t);
}
var Model = new ViewModel
{
Teachers = db.Teachers.ToList(),
};
return View(Model);
}
View
@model IEnumerable<Ability.Models.ViewModel>
<h2>Teachers at Thomas More</h2>
...
@foreach (var Teacher in Model)
{
<tr>
<td>
@Teacher.FirstName
</td>
<td>
@Teacher.LastName
</td>
<td>
@Teacher.Email
</td>
<td>
@Teacher.Campus
</td>
</tr>
}
I'm not sure if it mathers, but I already tried doing several things including changing my loop to
@foreach (var Teacher in Model.Teachers)
but then I receive a similar error
'IEnumerable' does not contain a definition for 'Teachers' and no extension method 'Teachers' accepting a first argument of type 'IEnumerable' could be found
Looking forward to any help I can receive!
I see a couple of things that doesn't make sense.
First of all, where do you use the teachers
?
Personally, I think that the following code is more reasonable:
public ActionResult Index()
{
IEnumerable<Teacher> teachers = Enumerable.Empty<Teacher>();
string campus = Request.Params["Campus"];
if (campus != null)
{
if (campus == "Alle")
{
teachers = (from t in db.Teachers
select t);
}
else
{
teachers = (from t in db.Teachers
where t.Campus == campus
select t );
}
}
else
{
teachers = (from t in db.Teachers
select t);
}
var Model = new ViewModel
{
Teachers = teachers
};
return View(Model);
}
Second, you have to initialize also the other properties of ViewModel
in the above action method.
Now let's go to the view. You pass there a model of type ViewModel
. When you want to iterate through the teachers sequence, you can try this:
@foreach (var teacher in Model.Teachers)
{
<tr>
<td>
@teacher.FirstName
</td>
<td>
@teacher.LastName
</td>
<td>
@teacher.Email
</td>
<td>
@teacher.Campus
</td>
</tr>
}
All the above makes sense provided that db.Teachers
is an IEnumerable<Teacher>
.
You're sending the type ViewModel
to the view:
var Model = new ViewModel
{
Teachers = db.Teachers.ToList(),
};
return View(Model);
But it's expecting the type IEnumerable<Ability.Models.ViewModel>
:
@model IEnumerable<Ability.Models.ViewModel>
That is, it's expecting a collection where you're providing an object .
Given the usage in the view, it seems like you should just change it to expect a single object:
@model Ability.Models.ViewModel
This would allow you to directly access the property you're looking for:
@foreach (var Teacher in Model.Teachers)
Side Note: The logic in your controller doesn't look correct. You conditionally create a teachers
variable, but then never use it. Instead, you just materialize all of the teachers in the database and send them all to the view. If you intend to see all of the teachers, you can remove most of that code. If you intend to see specific teachers, you would want to use the variable you created. Reference @Christos' answer for a practical example of that.
Your model is a list of ViewModels. You needed to use @foreach (var Teacher in Model.Teachers)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.