2017-02-11 85 views
2

我是新来MVC5,只是想掌握使用的ViewModels的。我的问题是如果我必须在我的ViewModel的控制器中实例化我的模型类。我正在制作一个数据库来组织账单,并且有一个映射到数据库表的Cash模型和一个用于查看/编辑数据的CashViewModel。我是否需要在MVC5的ViewModel中实例化Model类?

这里是我的模型:

public class Cash 
{ 
    public int CashId { get; set; } 
    public decimal CashAmount { get; set; } 
    public int CashTypeId { get; set; } 
    public DateTime DateModified { get; set; } 
    public CashType CashType { get; set; } 
} 

这里是我的ViewModel:

public class CashViewModel 
{ 
    public int CashId { get; set; } 
    public decimal CashAmount { get; set; } 
    public int CashTypeId { get; set; } 
    public SelectList CashTypeSelectList { get; set; } 
} 

这里是我的控制器:

public ActionResult Create([Bind(Include = "CashAmount,CashTypeId")] CashViewModel cashVM) 
    { 
     if (ModelState.IsValid) 
     { 
      var cash = db.Cashes.Create(); 
      cash.DateModified = DateTime.Now; 
      cash.CashAmount = cashVM.CashAmount; 
      cash.CashTypeId = cashVM.CashTypeId; 
      db.Cashes.Add(cash); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     ViewBag.CashTypeId = new SelectList(db.CashTypes, "CashTypeId", "CashTypeName", cashVM.CashTypeId); 
     return View(cashVM); 
    } 

我创建了现款车型的一个实例并将我的ViewModel类映射到我的模型类。它是否正确?当我开始在一个ViewModel中有多个具有多个属性的模型的项目时,这看起来很快就会失控。

所有的问题,我看文章是不是太模糊或过于详细,如果有一些已经在那里我找不到任何我的具体问题,不好意思。

+0

你的行为是否正确。请参阅[什么是MVC中的ViewModel?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc)。然而,删除你的'ViewBag.CashTypeId = new SelectList(....)'并用'cashVM.CashType = new SelectList(db.CashTypes,“CashTypeId”,“CashTypeName”);'(注意不是第4个参数) - 在视图中应该是'@ Html.DropDownListFor(m => m.CashTypeId,Model.CashType,...)' –

回答

2

的ViewModels基本上都是提供视图和控制器,它看起来像你这样做之间的DTO。然而,您的模型看起来不正确,因为您应该只有CashType,而不是CashTypeId,因为CashType模型具有Id和Cash对其的引用。同时存在的问题是他们不保持同步,我甚至不记得哪一个EF选择权威。

除此之外,它看起来像你已经想通了。您的ViewModel具有一个SelectList,其中包含要呈现的视图的值,以及一个用于客户端的CashTypeId以将值分配给。如果您的主实体没有CashTypeId,您必须创建一个新的CashType对象并为其分配正确的ID(假设这是实体框架)。

最后一个忠告:不要在你的控制器做这些DB操作。看看repository pattern,甚至可以在它们之间建立一个业务层。

+0

感谢您的回复。我一直在阅读Wrox专业ASP.NET MVC 5书,通过MVC Music Store示例,他们一直在使用外键ID在数据库中创建外键关系。我只是测试了你对某些测试类所说的内容,并在另一个设置中引用了一个模型中的外键关系... TIL。为了跟进存储库,他们有基本的CRUD功能,但是我需要将我的viewmodel数据映射到所有模型以更新规范化表格吗? – Andy

+0

您的存储库只能处理模型/实体。 ViewModels不应该存在于ASP.NET MVC项目之外。所以是的,你需要将ViewModel映射到Model。有一个名为AutoMapper的软件包可以帮助解决这个问题,尽管我没有亲自使用它。 –

1

我正在创建一个Cash模型的实例,并将我的ViewModel类映射到我的模型类。它是否正确?当我开始在一个ViewModel中有多个具有多个属性的模型的项目时,这看起来很快就会失控。

没有什么错,你在做什么。但是,对于从您的域模型到视图模型(视图模型)的映射,您可以使用库为您执行映射。我使用AutoMapper。想象一下,你有这样的:

public class Cash { 
    public string Prop1 { get; set; } 
} 

public class CashViewModel { 
    public string Prop1 { get; set; } 
} 

在你Application_Start() start方法,可以指示AutoMapper如何从你的域模型映射到你的模型像这样的观点:

protected void Application_Start() 
{ 
    // ReverseMap will do vice-versa mapping 
    // If property names are the same, then AutoMapper will take care of it 
    // for you. 
    Mapper.Initialize(x => x.CreateMap<Cash, CashViewModel>().ReverseMap()); 

    // Of course you will have many cases where the property names 
    // are different 
    // For that case you will need to do this 
    // Imagine your model has a property called Name and view model has 
    // FirstName 
    Mapper.CreateMap<CashViewModel, Cash>() 
      .ForMember(model => model.Name, map => map.MapFrom(vm => vm.FirstName)); 
} 

然后在你的控制器,你只是这样做,从一个视图模型转换成域模型:

var model = Mapper.Map<Cash>(cashViewModel); 

这种方法的好处是,所有你的映射会在一个地方。总之,here是一篇很好的文章,涵盖了大部分您正在寻找的内容以及更多内容。

相关问题