【问题标题】:Web API is it necessary to have ViewModels layer classes?Web API 是否需要有 ViewModels 层类?
【发布时间】:2018-08-23 11:22:09
【问题描述】:

当我使用 Web (MVC) 时,我总是创建一个单独的类层。这些类通常与 DTO 类相同,但具有 [Display(Name = "Street")] 和验证等属性。但是对于 web api 显示属性不是必需的,FluentValidation 可以使用验证。 Api 控制器应该返回 ViewModels 类还是 DTO 类也可以?

【问题讨论】:

    标签: asp.net-web-api asp.net-mvc-5 viewmodel dto


    【解决方案1】:

    答案一如既往......这取决于。

    如果您的 API 服务于多个客户端、应用程序等,那么返回 DTO 是更好的选择。

    ViewModel 特定于 MVC 客户端并且应该已经准备好显示,这意味着数据应该已经以特定方式格式化,一些字段可能组合在一起,它们应该满足显示页面的任何要求。出于某种原因,它们被称为 ViewNode。关键是它们很少与 API 返回的数据完全相同,这应该更通用一些,并遵循一定的模式以使其对用户有意义。

    如果您的 ViewModel 完全相同并且您只有一个客户端,那么您是否要创建一组重复的类来避免具有属性,这取决于您。

    从 DTO 到 ViewModel 以及反之亦然的映射并不复杂,但这个过程确实引入了更多的复杂性,增加了一层。

    但不要忘记一件事。无论任何 UI 的要求如何,API DTO 都应该返回它们在任何实体上的数据。无论如何,需求可能会发生变化,添加或丢弃新字段。发生这种情况时,您很可能不理会 API,而只需更改您的 ViewModel。

    您的 ViewModel 特定于 UI 页面,并且应该只包含该页面所需的数据。这意味着您可以为相同的数据创建多个 ViewModel,只是每个视图的显示要求不同。

    我的投票倾向于保持 ViewModel 和 DTO 分开,即使此时它们完全相同。事情总是在变化,这是你可以真正做好准备的事情之一。

    【讨论】:

    • 那么,您建议始终将 VM 用于 MVC,并将 DTO 用于 API?
    • 没错,它引入了一个分离层,它允许您添加多个由 DTO 提供服务的客户端
    • 但是 API 也是一个客户端层 :)
    【解决方案2】:

    实际上,我们希望如何返回响应取决于应用程序的架构。在这种情况下,是的,我们可以返回 DTO 类,但我认为这不是一个好方法,因为我们应该创建一个单独的资源类,它将与 DTO 映射然后返回。请看下面的例子:

    public class CustomerDTO
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int DepartmentId { get; set; }
    }
    
    public class CustomerResource
    {
        [JsonObject]
        public string Name { get; set; }
        [JsonObject]
        public string Department { get; set; }
    
    }
    

    假设我们有 CustomerDTO 类,我们希望返回以下 json 格式的响应

     {
    "name":"Abc xyz",
    "department":"Testing"
    }
    

    所以在这种情况下,我们应该有一个单独的类,当我创建 CustomerResource 时,它​​将作为对最终用户的响应返回。在这种情况下,我们将创建一个映射器,它将 DTO 与资源对象进行映射。 而且通过这个实现,我们可以独立测试资源

    【讨论】:

    • 在我看来,返回的 Dto 将具有相同的 JSON 格式(不取决于 [JsonObject] 属性)。当然,当返回的模型与 DTO 模型不同时,创建视图模型会更好,但是当它相同时......创建视图模型的任何理由? [JsonObject] 属性是一个原因,但在我们的例子中这个属性没有意义......
    • 实际上我已经根据我当前的应用程序给出了答案,我们有一个产品支付网关,我们在其中向我们的商家提供 REST API,我们正在使用微服务架构,因此我们创建了一个公共资源(即ViewModels)由多个微服务共享(实现 DRY 原则),是的,你是对的,在你的情况下没有使用 [JsonObject]。
    • 那么拥有这些资源类你能得到什么?另外,当您说您独立测试资源时,您是什么意思?该资源是一个没有功能的简单类,那么您到底在测试什么?
    猜你喜欢
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    相关资源
    最近更新 更多