【问题标题】:Is the View in MVC supposed to know the about the Model Data?MVC 中的视图是否应该了解模型数据?
【发布时间】:2017-03-09 12:30:10
【问题描述】:

我对 MVC 和 thisthis 等类似问题进行了一段时间的研究。

但是,他们没有回答我的问题。在很多 MVC 示例(ASP.NET MVC 和 JAVA MVC)中,它们通常为模型提供字段 E.G(姓名、年龄等),然后允许视图“读取”这些字段。

但据我了解,视图不应该知道模型,因为如果视图知道,那么它不是(正确)封装的。

但是,图片显示视图知道模型以显示正确的数据。

如果我理解正确的话,模型可以是系统的业务逻辑,而视图不应该与之连接。

假设我的模型从数据库中获取数据,那么仍然是我的模型是我的业务逻辑而不是数据库,还是我想错了?

所以我的问题是

  • 视图是否应该知道模型以使用正确的数据?
  • 控制器的工作是从 E.G 数据库中获取数据并从中创建模型,并且视图应该使用模型数据进行显示吗?
  • 什么是模型业务逻辑? (请不要用字段来解释)

【问题讨论】:

  • 我喜欢认为我的 UI 由三个部分(Model.View、Controller)组成。这些仅形成应用程序的顶层,下面是 BL,下面是持久性。因此,MVC 部分中的模型只是 UI 的模型,在这种情况下,是的,视图需要了解模型。

标签: c# model-view-controller architecture


【解决方案1】:

其中很多都可以解释。有多种方法,最终选择最适合您的方法。如果有帮助,我的方法如下。

视图是否应该知道模型以使用正确的数据? 是的。视图有一个模型导入指令,可以在渲染时绑定到它。如果视图对它正在访问的模型一无所知,那么它如何绑定到数据。

控制器的工作是从 E.G 数据库中获取数据并从中创建模型,并且视图应该使用模型数据进行显示吗? 不,控制器不应该对数据层的实现一无所知。控制器的唯一工作应该是调用构建视图模型所需的服务。

什么是模型业务逻辑? (请不要用字段来解释) 不确定确切的术语“模型业务逻辑”。模型可用于描述域模型或在本例中为视图模型。业务逻辑是您对由某些服务填充的业务或域模型对象执行的操作。

正如您所说,我处理 ViewModel 和业务逻辑的方式是分离域模型,例如Customer 或 Order 在单独的 dll 中,并让这些域对象由服务填充。然后,您的视图模型将成为域模型对象的组合。

总而言之.. 控制器会调用使用数据层的服务,这些数据层会返回您填充的域对象。然后可以使用这些来填充您的视图模型,然后由视图使用。

我在下面添加了一个非常简单的方法,希望能为您指明正确的方向。

public class MyController
{
    [HttpGet]
    public ViewResult GetCustomer(int customerID)
    {
        var myViewModel = new CustomerViewModel();
        var myService = new MyServiceLayer();

        var myCustomerDetails = myService.GetCustomerDetails(customerID);

        myViewModel.Customer = myCustomerDetails;

        return View("CustomerDetails", myViewModel);
    }
}

public class CustomerViewModel
{
    public CustomerDomainObject Customer { get; set; }
}


public class CustomerDomainObject
{
    public string Name {get;set;}
}

public class MyServiceLayer
{
    public CustomerDomainObject GetCustomerDetails(int customerID)
    {
        var myCustomer = new CustomerDomainObject();
        var dataLayer = new MyDataLayer();
        var myCustomerData = dataLayer.GetCustomerDetails(customerID);

        var myDataRow = myCustomerData.Tables[0].Rows[0];
        myCustomer.Name = myDataRow["Name"].ToString();

        return myCustomer;
    }
}

public class MyDataLayer
{
    public DataSet GetCustomerDetails(int customerID)
    {
        //Execute proc etc...
        return new DataSet();
    }
}

【讨论】:

  • 当您的意思是客户或订单在一个单独的 dll 中并且这些域对象由服务填充您是指什么类型的服务?只是为了让我感受一下。
  • 一个业务类,如果你喜欢的话,它位于一个单独的类库项目中。这将使用您的数据层从数据库中获取所需的数据。然后它可以使用数据库数据填充域对象并传回控制器。
  • 我用一个演示主体的简单示例编辑了我的答案。
  • 这对我帮助很大。谢谢。
【解决方案2】:

在 ASP.NET MVC 中,您拥有强类型视图。这是一件非常棒的事情,可以让您在构建视图时轻松访问模型属性。您会很容易注意到这一点,因为每当您尝试访问 @Model.Name 之类的属性时,IntelliSense 都会起作用。如果它应该或不应该是强类型的,恕我直言,它只是根据你的需要传递,使用强类型视图没有缺点。每当您编写视图时,它都会为您提供大量帮助,并且您肯定会减少运行时错误。

对于“模型业务逻辑”,我会说您的模型中肯定有很多逻辑,但这并不像听起来那么简单。您可能必须使用模式并拥有负责一件事的小类。

看这个链接:https://msdn.microsoft.com/en-us/library/hh404093.aspx

【讨论】:

    【解决方案3】:

    一般来说,将域模型与其视图表示完全分开是一个好主意。领域模型包含整个业务逻辑,可能非常复杂。此外,表示层通常需要极其简化的对象(只是数据结构,没有任何业务逻辑)。特定的视图技术可能会对对象施加严格的限制。除此之外,我们经常更改/聚合域对象以满足最终用户的特定需求(通过创建专门的 DTO)。因此,由于表示层和领域层是如此不同(领域模型永远不应该依赖于视图),我经常将它们完全分开。这样可以创建更灵活的设计。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-18
      • 2011-10-16
      • 2011-03-01
      • 2011-05-26
      • 1970-01-01
      • 2015-03-13
      • 2012-11-16
      相关资源
      最近更新 更多