Reputation: 940
How does the interaction between Model and ViewModels should be? Supposing I've a class named Customer with Id and Email properties, and another one CustomerModel with the very same properties.
This is the scenario:
I load a view based on that CustomerModel, this view has a form. As form is submitted, the CustomerModel is passed upon to the Action, let's say, Save. In the Save action should I create an instance of Customer and populate it property by property?
Example below:
ActionResult Save(CustomerModel cm)
{
//validation goes here
Customer c = new Customer();
c.Id = cm.Id;
c.Email = cm.Email;
context.Entry<Customer>(c).State = System.Data.EntityState.Modified;
context.SaveChanges();
//continue
}
Given I read in an earlier post that I should avoid use model class for both purposes, data and view model, I ask:
Is that correct way to implement it?
Upvotes: 2
Views: 237
Reputation: 21255
How does the interaction between Model and ViewModels should be?
The view models describe data to the view. It is for presentation logic and providing data to the view. The models are for describing data from your data source such as sql or a file.
Example of stuff in your view models:
public class CustomerViewModel
{
public long Id { get; set; }
public bool IsFoundingMember { get { return Id < 1000; } }
public string Name { get; set; }
public bool IsABaggins { get { return !string.IsNullOrWhiteSpace(Name) ? Name.EndsWith("Baggins") : false; } }
}
Example of stuff in your models
public class Customer
{
public long? Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public DateTime? DateOfBirth { get; set; }
}
I would try grouping the logic into functions for maintainability.
Say:
ActionResult Save(CustomerModel cm)
{
if(!ValidateCustomerModel(cm))
{
//Deal with invalid data
}
UpdateCustomer(cm);
//continue
}
public bool ValidateCustomerModel(CustomerModel model)
{
//Do stuff
return true;
}
public void UpdateCustomer(CustomerModel model)
{
Customer c = new Customer();
c.Id = cm.Id;
c.Email = cm.Email;
context.Entry<Customer>(c).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
After you have all of your CRUD logic separated out you could make some classes for that logic and look into Unity, Ninject, or plain old constructor injection.
e.g. Constructor Injection
public class MyController : Controller
{
private readonly ICustomerDL _customerDL;
public MyController(ICustomerDL customerDL)
{
_customerDL = customerDL;
}
//Load your implementation into the controller through the constructor
public MyController() : this(new CustomerDL()) {}
ActionResult Save(CustomerModel cm)
{
if(!ValidateCustomerModel(cm))
{
//Deal with invalid data
}
_customerDL.UpdateCustomer(cm);
//continue
}
public bool ValidateCustomerModel(CustomerModel model)
{
//Do stuff
return true;
}
}
public interface ICustomerDL
{
void UpdateCustomer(CustomerModel model);
}
public class CustomerDL : ICustomerDL
{
public void UpdateCustomer(CustomerModel model)
{
Customer c = new Customer();
c.Id = cm.Id;
c.Email = cm.Email;
context.Entry<Customer>(c).State = System.Data.EntityState.Modified;
context.SaveChanges();
}
}
The benefit is all of your logic will be clean and structured which will make Unit Testing and code maintenance a breeze.
Upvotes: 1