1
votes

I have a question regarding organization of properties in viewModel. As far as I understand the viewmodel should be as simple as possible, and the main thing that it should do is bind data to view.

The question is how to distinguish properties in viewmodel from BL model. I mean for example I have a BL model like :

   public class UserDetailsModel
    { 
        public string UserName {get;set;}
        public string SomeInfo{get;set;}
        public string AnotherInfo{get;set;}
        public string Anything{get;set;}
        public string Something {get;set;}
        ...

     }

then I have another BL model say:

 public class UserInfoModel
        { 
            public string Info1{get;set;}
            public string Info2{get;set;}
            public string Info3{get;set;}
            public string Info4{get;set;}
            public string Info5 {get;set;}
            ...

         }

Now the question is what is the best practices to Create ViewModel that should have data of both BL models.

1) Duplicate the properties from 2 models , and use Default Model binding to transfer data from view to controller , then create BL models from ViewModels and via repository update data ? In this case we have code duplication ...

2) ViewModel should look something like:

 public class UsersIdentificationViewModel 
        {
            public UsersIdentificationViewModel()
            {
                UserInfoModel = new UserInfoModel();
            }

            public UserInfoModel UsersInfo { get; set; }

            public UserDetailsModel UserDetails { get; set; }   

        }

The default binding will not work in this case (Correct me if I am mistaking) and I should write custom Model binder or something like this... What approach is better for unit testing , or maybe there is another approach ?

1
Your option 2 would work. Nested viewmodels is supported. Have you tried it?Pablo Romeo
I will try this way , thanksStringBuilder

1 Answers

0
votes

If you need to use the properties from the BL models inside your view model, the best option is to embed the BL models as properties inside your view model. As you said that way you will avoid duplication of the properties names, which is obviously good thing.

public class UsersIdentificationViewModel 
{      
    public UserDetailsModel UserDetails { get; set; }        
    public UserInfoModel UsersInfo { get; set; }

    // I added this propery so I can round up the binding process in case the properties are simple types
    public string SomeSimpleProperty { get; set; }
}

The default model binding will work in this case. Because the parameter of your action method will be complex type UsersIdentificationViewModel, the DefaultModelBinder class with reflection will get the public properties, check if they are simple or complex types and then bind to each of them.

In case the property is complex type, the process is repeated. The set of public properties are obtained, and the binder tries to find values for them. The property names are nested. For example: to set value for UserName, the model binder will look for a nested data item UserDetails.UserName.

If the properties are simple types, the binder will look for a data item in the request that has the same name as the property. For example: the SomeSimpleProperty property will cause the binder to look for a SomeSimpleProperty data item. I found this link to be very helpful explaining model binding.

For unit testing you will not have any problems or differences if you choose case 1 or 2.