3

I've read couple of posts on using ViewModel in ASP.net MVC and realized it is different from "ViewModel" in M-V-VM pattern.

ViewModel are used in order to avoid having Model being accessed directly from View but is it good approach to have properties of type (defined at Model layer) in ViewModel? Which means eventually we need to include Model namespace to ViewModel.

E.g.

Model
1. YesNoTBDValue entity/POCO class

public partial class YesNoTBDValue
{
    public int Id { get; set; }
    public string Name { get; set; }
}

2 YesNoTBDValue class used in Project entity (defined in Model itself)

public partial class Project
{
     public virtual YesNoTBDValue IsAvailable { get; set; }
}

View Model
1. ProjectEditViewModel

public class ProjectEditViewModel
{
HERE TO INCLUDE YesNoTBDValue CLASS, I NEED TO INCLUDE MODELS 
OR THERE IS BETTER WAY?
    public List<YesNoTBDValue> YesNoTBDValues { get; set; }
    public int IsAvailableSelectedItemId { get; set; }
}

Controller
Project Controller (in edit action creating new instance of view model)

ProjectEditViewModel projectEditViewModel = new ProjectEditViewModel
{
    YesNoTBDValues = db.YesNoTBDValues.ToList()
};

View
Showing DropDownList from YesNoTBDValues list and keeping selected item in IsAvailableSelectedItemId

@Html.DropDownList("IsAvailableSelectedItemId ", 
new SelectList(Model.YesNoTBDValues, "Id", "Name",
            Model.IsAvailableSelectedItemId ))

Please suggest me how it should be properly coded.

Repeating question: Should ViewModel include Model's namespace? In my example YesNoTBDValue is defined in Model and to use it I am using Model's namespace

/ ANOTHER APPROACH /

Not satisfied with my existing approach, I downloaded the Microsoft Nuget Gallery source code from github and realize that they have never used MODELS inside VIEWMODEL which makes sense to me. I changed above code a little bit (in order to remove reference of Model from ViewModel) and found it working great.

Here are my changes:

Model No Changes, Same as it is

View Model
1. Create Replica of YesNoTBDValue class say YesNoTBDValueViewModel

public class YesNoTBDValueViewModel
{
   public int Id { get; set; }
   public string Name { get; set; }
}

2 Use this ViewModel in ProjectEditViewModel and remove Model reference

public class ProjectEditViewModel
{
     public List<YesNoTBDValueViewModel> YesNoTBDValues {get;set;}
     public int IsAvailableSelectedItem {get;set;}
}

Controller Change in way of populating these values. (In Edit action)

ProjectEditViewModel projectEditViewModel = new ProjectEditViewModel
{
    YesNoTBDValues = db.YesNoTBDValues.Select(
                x => new LMSPriorTool.ViewModels.YesNoTBDValueVM
 {
    Id = x.Id,
    Name = x.Name
 }).ToList()
}

And found after these changes, it is working fine too. I like this second approach as in this Models and ViewModels are totally separated from each other. Keeping this question open for further discussion.

Please throw some light if I'm missing something here.

tereško
  • 58,060
  • 25
  • 98
  • 150
Rohit
  • 6,365
  • 14
  • 59
  • 90
  • Why do not use MVC? MVVM is a derivation of PM, which is for rich UI applications. I am not sure MVVM is suitable for ASP.net also. – Bill Zhang Jun 30 '13 at 00:43
  • @BillZhang: Here I'm not referencing MVVM pattern. In fact View Model in ASP.net MVC4 is not same as View Model in MVVM pattern. There has been huge debate over need of ViewModel in ASP.net MVC4 (at StackOverflow itself) and overall (in those debates) it is preferred to have ViewModel. What's your thought? – Rohit Jun 30 '13 at 01:31
  • ViewModel is a special Model for View. In WPF and PM pattern, View and Presenter communicate through DataBinding and Commanding so Presenter evolves into a more Model like object so called ViewModel. I am not familiar with ASP.Net/MVC, if in your case the Model cannot satisfy what View need, for example, complicated data converters needed, you could bring in a ViewModel like layer to make Model more UI friendly. I think that is quite reasonable. – Bill Zhang Jun 30 '13 at 02:03
  • Even I've came from kind of same experience. My past experience was with WPF application and used MVVM pattern. But there is difference between two. You're right about MVVM in WPF. – Rohit Jun 30 '13 at 02:09

1 Answers1

1

I try to keep the ViewModel containing only simple types which are natural in the context of the view. That way I keep rendering logic in the view to a minimum and keep the view clean.

Your ViewModel can be represented very simply with something like:

public class ProjectEditViewModel
{
    public int YesNoTBDValueSelected { get; set; }
    public SelectList YesNoTBDValueOptions { get; set; }
}

or

public class ProjectEditViewModel
{
    public int YesNoTBDValueSelected { get; set; }
    public IEnumerable<SelectListItem> YesNoTBDValueOptions { get; set; }
}

Now logic for generating SelectList goes in your Project <-> ProjectEditViewModel mapping and is kept out of View.

fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253
  • Even I implemented this way only very first time but I was caught up in "How to pass selected drop down item to Controller post action" Now everything is setup, it did not take much time to change everything to use SelectList. (Still did not able to use IEnumerable it throws error like "SelectListItem does not contain property with Name 'id'). Will upload the code here shortly – Rohit Jun 30 '13 at 17:51
  • Surprised to see my edit was not approved. I added complete code for implementing with this approach. That was definitely helpful for some1. – Rohit Jul 01 '13 at 18:21
  • 1
    @RohitKandhal you can add your new code as another answer, I'm sure it will help someone. – fearofawhackplanet Jul 01 '13 at 19:33