2013-08-04 25 views
3

我有一个asp.net-mvc网站,几乎是一个CRUD应用程序,但我也做了一些在webview之外添加&更新(从电子表格等上传)。 Based on this article,我试图获得尽可能多的MVC项目之外的逻辑到一个单独的共享项目,所以我可以在所有情况下重复使用相同的代码,我试图隔离和分离我的“读取”viewModels绑定到用户界面显示来自“编辑”视图的模型,这些模型表示在表单文章中发布到服务器的内容。在asp.net-mvc中,将我的“EditViewModel”类移到我的MVC Web项目之外是错误的吗?

我有解决方案的一些项目(domainobjects,importexport等),它们与其他的解决方案,加上MVC项目共享已在MVC项目下面的目录

  • 控制器
  • 查看
  • 的ViewModels
  • 脚本
  • EditViewModels

我的ViewModels文件夹代表我(绑定到我的意见的对象的容器对象通常包括:

  • 域对象和
  • 一堆SelectListItem的IEnumerable的填充UI下拉菜单等

是这样的:

public class OrderViewModel 
{ 
     public Order MyOrder {get;set;} 
     public IEnumerable<SelectListItem> OrderTypes {get;set;} 
     public IEnumerable<SelectListItem> Sizes {get;set;} 
} 

我EditViewModels文件夹代表的对象THA TI是从形式发布到服务器,因此它们通常是简单的平面物体只primatives我那么像这样添加或更新我的数据库之前填充域对象有:

public class OrderEditViewModel 
{ 
     public int Id {get;set;} 
     public int OrderTypeId {get;set;} 
     public int SizeId {get;set;} 
} 

我的主要问题是,当我有一个方法在我的控制器类,通常看起来像这样(简化):

public ActionResult Update(OrderEditViewModel order) 
    { 
     var existingOrder = _repository.GetOrder(order.Id); 
     existingOrder.Name = order.Name; 
     existingOrder.Size = _repository.GetSize(order.SizeId); 
     existingOrder.Price = order.Price; 
     _repository.Save(existingOrder); 
     return Json(Result = "Success"); 
    } 

我试图找出如何让尽可能多的代码尽可能MVC项目之外但这迫使我把所有我的班中MVC项目之外的EditViewModel,以便可以重用这些对象。

有没有人看到这些“Post”数据结构归类于MVC项目外的任何错误。鉴于它是一个“viewmodel”类,将它从视图中移走是不对的,但我没有看到任何其他方式在MVC项目之外共享此代码。也许这里的“viewModel”这个名字可能错了吗?

回答

5

您的视图模型是针对你的意见,而不应是相关的任何东西。它们包含没有其他人应该关心的事情,例如您的选择列表。因此,他们应该留在你的用户界面中。

的文章,在我看来是建立在业务逻辑依赖于UI(或至少所述UI模型..即视图模型)的情况下,我认为这是错误的做法。如果业务逻辑不知道用户界面是什么,UI应该能够使用业务逻辑。它可能是一个网站,一个胖客户端,一个移动客户端,一个网络服务等......通过使这个逻辑取决于你的视图模型,你现在正在使任何未基于web的服务都依赖于这些服务。

然而这是一个简单的CRUD应用程序,并在简单的CRUD应用程序,你可以经常采取了很多快捷键,因为它只是不值得额外的工程设计工作。我通常不会直接在视图模型中将域对象传递给视图。但在这种情况下,它可能是最好的选择。

如果你想这样做“正确的”,但是,那么你需要创建的担忧更多的分离。您的域和用户界面层需要更多的分离。您可以创建单独的视图和域模型,然后在它们之间进行映射。这可以防止业务层知道有关UI的任何信息。

我可能会创建一个处理您的逻辑的服务层。例如:

_orderService.UpdateOrder(order.Id, order.Name, order.Price); 
+0

我倾向于同意你的看法。 。 – leora

0

你可以使用你的项目,一个服务架构,所有功能和数据库查询是在这个文件中,你可以使用它只是通过将此代码

IOrderService<Order> service = new OrderEntityService(); 

,并使用它像

service.Create(Order) or service.Update(); 
-1

OrderEditViewModelOrderViewModel都是'ViewModels'结尾的一天。国际海事组织,他们可能会一起呆在同一个项目中,即使在同一个'ViewModels'文件夹中。你可以在ViewModels下为你的'EditViewModels'创建一个子文件夹。

现在,当您要清洁/整理控制器操作时,您可能需要使用AutoMapperValueInjecter。您正手动映射域实体和视图模型。这是一个令人厌烦的工作。随着AutoMapper你可以这样做:

var customerInfo = Mapper.Map<CustomerViewModel, CustomerInfo>(customerViewModel); 
+0

这不会谈论我的要求,然后在哪里放置更新逻辑? – leora

+0

@leora _“我试图弄清楚如何在MVC项目之外获得尽可能多的代码。”_ 这可能是我的要求。无论如何,谢谢你鼓励我。 –

+0

理解,但问题的核心部分是应该将这些EditViewModel类移到应用程序的业务端还是保留在UI中,如果是这样的话,数据更新逻辑去哪里 – leora

2

在我的情况下,我在读取(视图)模型和写入模型之间做出区别。

阅读模型对视图非常具体,它们可以包含选择列表和格式化和本地化的内容。您不应该将此模型移到您的UI项目之外。当然,你可以用你的模型做一个独立的程序集,或者你可以为每个模块创建一个程序集,但是你不应该从你的领域层使用这些模型。

写模型 - 在我看来 - 并不是特定于您的用户界面。相反,它们表示该命令所需的数据(例如SaveUserCommand)。它们可以包含验证属性,因此您的域图层可以轻松验证它们,并且可以由域图层和UI共享它们。在我的项目中,每个命令都有一个类(例如SaveUserCommand,EditUserCommand,DeleteUserCommand)和相关模型(SaveUserModel,EditUserModel)。有人会评论,他们还包含一些特定于UI的代码(例如属性或属性本身的IClientValidateable itnerface),并且至少IClientValidateable接口是我愿意忽略的问题,以减少模型数量。我对这种方法的经验(我也尝试过其他方法)表明,这些模型非常简单,并且很容易绑定到这些模型。

有时您也会遇到问题,您想在编辑视图中显示一些附加信息。而是将所有这些信息的viewbag的,我会有另一种模式,例如:

class UserEditModel 
{ 
    string Password; 
} 

UserEditViewModel 
{ 
    DateTime Modified; 

    UserEditModel Edit; 
} 

所以我的建议是:

  1. 创建写模式,拥有所有的数据和验证逻辑是特定于您的用例。
  2. 创建包含要显示的所有数据的视图模型,并尝试不使用ViewBag。
  3. 如果您有表单,请将写入模型添加到视图模型中。写模型将所有数据通过POST发送回服务器,然后直接发送到您的域层。
0

我用四个一“层”的两个组件

有三个命名空间,只是一个普通的类库项目

{}应用装配的.app。

1){}应用为.MODEL域模型

2){}应用。数据用于使用存储库模式

3){}应用数据。服务的所有业务逻辑

{应用程序}。用于UI的WebUI程序集,这是MVC项目

控制器只调用服务和服务通过存储库获取和更新数据。

没有为您的应用程序需要做的每一项操作的服务API,即

OrderServices.Update(existingOrder)

OrderServices.Approve(existingOrder)

服务层只知道域模型,而控制器只是使用从服务获取的域模型来组装视图模型,将它们发送到视图,并使用从视图获取的视图模型来准备域模型,以将它们发送到适当的服务。

这样你就可以最终建立一个{}应用程序或.WebAPI任何使用相同{}应用程序组件。应用程序重用所有buissiness逻辑并保持viwemodels属于他们的地方(在WebUI项目)

希望这有助于。

此致敬礼。

0

对我而言,奇怪的是你尽可能多地关注你的应用,但是你仍然让你的MVC控制器包含很多你的逻辑。您试图共享对象和模型,但添加新OrderEditViewModel的逻辑不共享,它被卡在该控制器中。

我试着做的是为我的每个控制器创建一个“助手”或“逻辑”类。然后将该逻辑或助手类注入到我的控制器中并包装在界面中。我的控制器可以通过助手类保存,编辑和删除项目,但不知道它是如何实际执行的。

我已经将这些逻辑类与模型一起共享给其他项目,允许大量的代码重用。问题是确保没有任何控制器的“HTTP'ness”潜入您的逻辑类中,因为这些必须在控制台或winforms应用程序中可用。所以你必须非常严格,并把很多东西,如HTTPSession或HTTPContext包装到接口中,然后才能有非HTTP实现。

0

那么,我理解你的情况,也倾向于DDD(域驱动设计)解决方案正如@MystereMan所言。

我有sepparates“型号” 3个类别的方法:

  1. 的ViewModels:拥有所有必要的用户界面中的显示内容数据
  2. RequestModels的信息:是否所有necesssary信息发送数据,后/获得/等)
  3. AutoBindModels:让所有被注入我的MVC结合模型(饼干,会议等信息。)

而最祁门功夫对于我用作DTO/POCO的所有类,实际上它们没有UI相关的代码,只是属性/计算的属性,并且可以容易地在任何其他项目中被UI项目引用。

您还可以创建一个Controller类,充当ASP.MVC项目之外的服务并将其扩展或注入到您的MVC控制器中。

希望它可以帮助...

0

我从来不重用(编辑)的ViewModels对象(这是不完全正确,我经常分享创建和更新,但并不总是之间的一个EditViewModel)。

我为特定视图设计我的ViewModels。因此,当用户界面发生变化时(不断变化),我无需妥协我的ViewModel。

尽管它们是相同的,我还是会创建两个不同的ViewModel。我完成重构共享ViewModels ..

我会回答是的你的问题。

希望它有帮助。

相关问题