C# 模型和视图模型应该如何交互?

C# 模型和视图模型应该如何交互?,c#,asp.net-mvc,model,viewmodel,C#,Asp.net Mvc,Model,Viewmodel,模型和视图模型之间的交互应该是怎样的? 假设我有一个名为Customer的类,具有Id和Email属性,另一个名为CustomerModel的类具有非常相同的属性 这是一个场景: 我加载一个基于CustomerModel的视图,这个视图有一个表单。表单提交时,CustomerModel被传递给操作,比如Save。在保存操作中,我是否应该创建Customer的实例并按属性填充它 示例如下: ActionResult Save(CustomerModel cm) { //validation

模型和视图模型之间的交互应该是怎样的? 假设我有一个名为Customer的类,具有Id和Email属性,另一个名为CustomerModel的类具有非常相同的属性

这是一个场景:

我加载一个基于CustomerModel的视图,这个视图有一个表单。表单提交时,CustomerModel被传递给操作,比如Save。在保存操作中,我是否应该创建Customer的实例并按属性填充它

示例如下:

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
  }
ActionResult保存(CustomerModel cm)
{
//验证在这里进行
客户c=新客户();
c、 Id=厘米Id;
c、 Email=cm.Email;
context.Entry(c).State=System.Data.EntityState.Modified;
SaveChanges();
//继续
}
鉴于我在之前的一篇文章中读到,我应该避免将模型类用于数据和视图模型这两个目的,我想问:

这是正确的实施方法吗?

模型和视图模型之间的交互应该是怎样的

视图模型向视图描述数据。它用于表示逻辑和向视图提供数据。这些模型用于描述来自数据源(如sql或文件)的数据

视图模型中的内容示例:

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; } }
}
为了便于维护,我会尝试将逻辑分组到函数中

说:

ActionResult保存(CustomerModel cm)
{
如果(!ValidateCustomerModel(cm))
{
//处理无效数据
}
UpdateCustomer(厘米);
//继续
}
公共bool ValidateCustomerModel(客户模型)
{
//做事
返回true;
}
public void UpdateCustomer(CustomerModel模型)
{
客户c=新客户();
c、 Id=厘米Id;
c、 Email=cm.Email;
context.Entry(c).State=System.Data.EntityState.Modified;
SaveChanges();
}
在将所有CRUD逻辑分离出来之后,您可以为该逻辑创建一些类,并研究Unity、Ninject或普通的旧构造函数注入

e、 g.建造师注入

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();
    }
}
公共类MyController:Controller
{
私有只读ICCustomerDL\u customerDL;
公共MyController(ICCustomerDL customerDL)
{
_customerDL=customerDL;
}
//通过构造函数将实现加载到控制器中
public MyController():此(新CustomerDL()){}
ActionResult保存(CustomerModel cm)
{
如果(!ValidateCustomerModel(cm))
{
//处理无效数据
}
_customerDL.UpdateCustomer(厘米);
//继续
}
公共bool ValidateCustomerModel(客户模型)
{
//做事
返回true;
}
}
公共接口ICCustomerDL
{
void UpdateCustomer(CustomerModel模型);
}
公共类CustomerDL:ICCustomerDL
{
public void UpdateCustomer(CustomerModel模型)
{
客户c=新客户();
c、 Id=厘米Id;
c、 Email=cm.Email;
context.Entry(c).State=System.Data.EntityState.Modified;
SaveChanges();
}
}

这样做的好处是,您的所有逻辑都将是干净和结构化的,这将使单元测试和代码维护变得轻而易举。

看起来不错。我可能会将逻辑(验证、将内容保存到数据库)分离到函数中以便于维护,并使用一些依赖项注入,如Unity,但它看起来非常干净。
CustomerModel
是视图模型,
Customer
是模型?你在他们之间看到了什么样的交互?也许交互是一个糟糕的词语选择,但是想法,疑问是很清楚的,不是吗?ViewModel应该只包含与视图相关的数据和行为。通常,将ViewModel映射到DomainModel(反之亦然)的最佳方法是使用第三方映射库,例如。谢谢,我会深入研究。我没问题。但这里的核心关注点是客户的实例化并填写其属性。从我得到的答案来看,我认为我走对了。@user1916886是的,视图模型用于描述视图中的数据,而模型用于转换数据源(sql、文件等)中的数据。您将在视图模型和模型之间完成少量映射逻辑(您可以查看
AutoMapper
,了解其中的一些内容)
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();
}
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();
    }
}