0

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);
        }
0

5 Answers 5

1

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?)

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

7 Comments

Thanks! and yes, Name is infact the device name. However non of the users already on the db are showing in the view.
Is the collection populated in the controller? Currently you appear just to be initializing a new List<UserDeviceViewModel>, and passing that.
That makes sense. How would i go about populating the list in the controller, what would i need to change to: var viewModel = new List<FaceToFaceWebsite.Models.UserDeviceViewModel>(); ?
That needs to be a separate question (and you need to include more information - are you using EF for example). I suggest to just hard code in one or two` UserDeviceViewModels` and set some properties to check first that the view actually works. Also you view model has a SelectList, which means you are generating a new SelectList for each User (not very efficient)
It could be something as simple as var viewModel = db.Users.Select(u => new UserDeviceViewModels() { User = u }).ToList() but as I noted above, your view model should not contain User, but instead the relevant properties of user, so it might be { UserID = u.UserID, CodeName = u.CodeName, etc) ]
|
1

Remove the Ienumerable!

@model FaceToFaceWebsite.Models.UserDeviceViewModel

Look in your controller:

public ActionResult Index() { var viewModel = new FaceToFaceWebsite.Models.UserDeviceViewModel();

return View(viewModel); }

2 Comments

even changing that back to var viewModel = new List<FaceToFaceWebsite.Models.UserDeviceViewModel>(); in the controller doesnt explain why i am im getting the error: CS1061: 'FaceToFaceWebsite.Models.UserDeviceViewModel' does not contain a definition for 'UserID' and no extension method 'UserID' accepting a first argument of type 'FaceToFaceWebsite.Models.UserDeviceViewModel' could be found (are you missing a using directive or an assembly reference?) Thankyou though.
You're trying to use the userid in the view which don't exist. Remove: @Html.DisplayNameFor(model => model.UserID)
1

You are passing List (IEnumerable<FaceToFaceWebsite.Models.UserDeviceViewModel>) , while your view code expected to be FaceToFaceWebsite.Models.UserDeviceViewModel

2 Comments

Doesnt explain why im getting the error: CS1061: 'FaceToFaceWebsite.Models.UserDeviceViewModel' does not contain a definition for 'UserID' and no extension method 'UserID' accepting a first argument of type 'FaceToFaceWebsite.Models.UserDeviceViewModel' could be found (are you missing a using directive or an assembly reference?)
Because List does not have UserID , you have to pass UserDeviceViewModel instead
1

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>

5 Comments

Thanks for your help with the controller, i need to use var viewModel = new List<FaceToFaceWebsite.Models.UserDeviceViewModel>(); return View(viewModel); However your suggestion for the fixing of the error just returned the same error. @{var UserDevice = Model.FirstOrDefault(); } <tr> <th> @Html.DisplayNameFor(model => UserDevice.UserID) </th>
DisplayNameFor() has an overload that accepts IEnumerable<TModel> so this is completely unnecessary (and has nothing to do with the error)
@StephenMuecke You are right. I have edited my answer
@Nilmag Sorry I have edited my answer to fix your error.
Thankyou, this has removed the error. However non of the users already on the db are showing in the view.
-1

As per given code snippet, your View mapping and data model not sync up.

can you just follow below steps

  1. clear all views.
  2. first display only user level info
  3. Verify user level info are you able to? next proceed further device level
  4. put device level loop for your devices collection (make sure your Device collection model m not sure about your "SelectedListItem"

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.