简体   繁体   中英

How should Models an ViewModels interact?

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?

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.

eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM