C# 模型和视图模型应该如何交互?
模型和视图模型之间的交互应该是怎样的? 假设我有一个名为Customer的类,具有Id和Email属性,另一个名为CustomerModel的类具有非常相同的属性 这是一个场景: 我加载一个基于CustomerModel的视图,这个视图有一个表单。表单提交时,CustomerModel被传递给操作,比如Save。在保存操作中,我是否应该创建Customer的实例并按属性填充它 示例如下: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
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();
}
}