Reputation: 573
I am having alot of difficult getting my viewmodel to work correctly. As a bit of context i am using a viewmodel to use two models from another project. These models contain the User information and thier chosen Device in a localdb. However i cannot currently use a view to display the data from both of those models on one view so i created a viewmodel.
However I am current recieving:
Error: 'System.Collections.Generic.IEnumerable' does not contain a definition for 'UserID' and no extension method 'UserID' accepting a first argument of type 'System.Collections.Generic.IEnumerable' could be found (are you missing a using directive or an assembly reference?)
This error is occurring for all of the model objects. If i can get around it it will be the first step to a functioning view model. Any help would be greatly appreciated.
User.cs - Model (in project: FaceToFace)
namespace FaceToFace.Model
{
public class User
{
public int UserID { get; set; }
public string CodeName { get; set; }
public bool UseBriefInstructions { get; set; }
public ICollection<RegimeItem> RegimeItems { get; set; }
public Device Device { get; set; }
public virtual ICollection<Grading> UserGradings { get; set; }
public User()
{
this.RegimeItems = new List<RegimeItem>();
Device = new Device();
}
}
public class RegimeItem
{
public int RegimeItemID { get; set; }
public Exercise RegimeExercise { get; set; }
}
}
Device.cs - Model (in project: FaceToFace)
namespace FaceToFace.Model
{
public class Device
{
public int DeviceID { get; set; }
public string Name { get; set; }
}
}
UserDeviceViewModel.cs (in project: FaceToFaceWebsite)
namespace FaceToFaceWebsite.Models
{
public class UserDeviceViewModel
{
public UserDeviceViewModel()
{
User = new User();
Devices = new List<SelectListItem>();
}
public User User { get; set; }
public IList<SelectListItem> Devices { get; set; }
}
}
PatientController.cs - Only a segment of the entire page to avoid spam (Project: FaceToFaceWebsite)
namespace FaceToFaceWebsite.Controllers
{
public class PatientController : Controller
{
private F2FData db = new F2FData();
public ActionResult Index()
{
var viewModel = new List<FaceToFaceWebsite.Models.UserDeviceViewModel>();
return View(viewModel);
}
}
}
Views/Patient/Index.cshtml (facetofacewebsite)
@model IEnumerable<FaceToFaceWebsite.Models.UserDeviceViewModel>
@*@model FaceToFaceWebsite.Models.UserDeviceViewModel*@
@*@model IEnumerable<FaceToFace.Model.User>*@
<h2>Your Patients</h2>
@*Showing @Model.Count() users*@
<p>@Html.ActionLink("Add New User", "Create")</p>
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.UserID)</th>
<th>@Html.DisplayNameFor(model => model.CodeName)</th>
<th>@*@Html.DisplayNameFor(model => model.Device.Name)*@Device</th>
<th>@Html.DisplayNameFor(model => model.DeviceID)</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.UserID)</td>
<td>@Html.DisplayFor(modelItem => item.CodeName)</td>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.DeviceID)</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.UserID }) |
@Html.ActionLink("Details", "Details", new { id = item.UserID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.UserID })
</td>
</tr>
}
</table>
So what i REALLY need to know is that by using model properties from another project, what do i have to do differently. What am i currently doing wrong? what should i do so that the USER information and the DEVICE information can be show.
UPDATE
Thanks to Stephen Muecke, the solution to the issue of the index view not displaying the user db data was solved by changing the Action result in the index controller to:
public ActionResult Index()
{
var viewModel = db.Users.Select(u => new UserDeviceViewModel() { User = u, Device = u.Device }).ToList();
return View(viewModel);
}
Upvotes: 0
Views: 4292
Reputation: 417
As per given code snippet, your View mapping and data model not sync up.
can you just follow below steps
Upvotes: -1
Reputation:
UserDeviceViewModel
contains a property named User
not UserID
(which is a property of User
. Your loop needs to be
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(m => item.User.UserID)</td>
<td>@Html.DisplayFor(m => item.User.CodeName)</td>
Note you table headers wont work in this case.
Note also you are not really using a true 'view model'. A view model contains only those properties which you need for display/edit in a view (not just for dumping other models). Based on the view code you have shown it should be something like
public class UserDeviceViewModel
{
public int UserID { get; set; }
public string CodeName { get; set; }
public int DeviceID { get; set; }
public IList<SelectListItem> Devices { get; set; }
}
Although you view contains a reference to property Name
(not sure what this is - perhaps DeviceName?) and your view does not use Devices
(have you omitted some of the view?)
Upvotes: 1
Reputation: 7348
Well you could pass the Correct type of ViewModel to your View:
In your View you have:
@model IEnumerable<FaceToFaceWebsite.Models.UserDeviceViewModel>
And in Controller you have:
var viewModel = new FaceToFaceWebsite.Models.UserDeviceViewModel();
return View(viewModel);
Try passing a List of your ViewModel:
var viewModel = new List<FaceToFaceWebsite.Models.UserDeviceViewModel>();
return View(viewModel);
OR:
In your View change this:
@model IEnumerable<FaceToFaceWebsite.Models.UserDeviceViewModel>
To:
@model FaceToFaceWebsite.Models.UserDeviceViewModel
WHY are you getting that ERROR Message?
Because your ViewModel doesn't have UserId, CodeName
etc.
BUT your User Class has UserId and CodeName
So In ViewModel you will access like this:
ViewModel.User.UserId
and ViewModel.User.CodeName
:
Like This:
<th>@Html.DisplayNameFor(model => model.User.UserID)</th>
<th>@Html.DisplayNameFor(model => model.User.CodeName)</th>
Upvotes: 1
Reputation: 776
You are passing List (IEnumerable<FaceToFaceWebsite.Models.UserDeviceViewModel>
) , while your view code expected to be FaceToFaceWebsite.Models.UserDeviceViewModel
Upvotes: 1
Reputation: 11002
Remove the Ienumerable!
@model FaceToFaceWebsite.Models.UserDeviceViewModel
Look in your controller:
public ActionResult Index() { var viewModel = new FaceToFaceWebsite.Models.UserDeviceViewModel();
return View(viewModel); }
Upvotes: 1