Can we use only DTO instead of ViewModel? [closed]
Asked Answered
L

3

9

We currently use DTO for Web API request and response

and use ViewModel to pass data to the View in MVC

Currently, we have:

  1. DTO as a separate project
  2. ViewModel is inside the UI project (another folder along with Controllers)

Only difference I see in our case is that DTO has to be passed over the wire and sent as JSON while ViewModel has to be passed inside the view to be render as HTML.

Should we mantain separate transfer objects for MVC applications and our App/other clients OR do both of these jobs through DTOs only i.e. passing DTO inside the View instead of ViewModel? What could be possible downside of it?

I read many responses here but there's no example and convincing reason to keep separate ViewModel and DTO in our case.

Latimer answered 29/5, 2018 at 5:30 Comment(1)
MVC technically does not require a ViewModel. It only requires a Model (there's only one M). A model can be used in multiple views. Are you asking if a Model is like a DTO, in a philosophical sense? Or are you asking if it is a requirement that each View have its own ViewModel (the answer is no)?Helles
H
20

Keep them separate

Bob did that once. He had a web site that displayed a user's profile, with things like their name and phone number. And he also had an API call that allowed a client to retrieve the same profile with the same information. So he used the same class for the web site's ViewModel and the API's DTO.

All was well at first. In fact, the business grew so well that Bob was able to sell his stock options and retire. The software engineering department became largely outsourced and people didn't really talk to each other.

A year later, the product owner, responding to customer requests, added a requirement that the profile page display not just the user's first and last name but also the user name and email address. A developer picked up the task and implemented it by adding a Login member to the ViewModel and populating it using AutoMapper. He believed the ViewModel was server side code and didn't think about it too much.

The company pushed a production live and the user name feature is a success. There was just one problem. All the API clients were now receiving JSON that contained the user's login, email address, and everything else, including their hashed password.

Don't be Bob.

Helles answered 29/5, 2018 at 6:47 Comment(2)
That's a great example. Thanks! But this could be solved if we have separate DTO for Apps and MVC. Then, why to have ViewModel?Latimer
If they are separate, then yes, you can use a "DTO" with your MVC views. Although I thought they were called models.6|12/2Helles
L
6

I can share my experience with this pattern as I have implemented it in a project. Consider the project as a simple CRUD application with distributed architecture and is divided into three solutions:

  • Project.Web (MVC Application)
  • Project.DTO (Plain C# classes)
  • Project.API (Web API Application)

Project.Web contains UI logic of the application and depends upon Project.API for all the CRUD operations, since database related operations are performed in Project.API.

Now comes Project.DTO, it contains plain C# classes and is used to transfer data to and fro.

Project.Web <---> Project.API

To make it more distributed, I have created Project.DTO as a Nuget Package and hosted it in Artifactory( you can use Nuget or any other repository) and consuming it using Nuget Package Manager. The main advantage with this approach is DTO classes are always versioned and easy to consume.

Coming to your question about keeping View Model and DTO separate, I can see the following points in favor of it:

  • Data transfer from API to Web and vice versa: It can be large and complex. Let say my application wants to create a client and add all its detail into the database such as Client Address, Client Communication, Client History etc. In Project.Web, we can have other details such as Session Related Data, UI specific data that need not require to be transfer from Web to API. Hence, creating a separate DTO makes sense that transfer only such data which is common to Web and API and is independent of projects.
  • Incoming Requests to API or Web: Let say, I have created a mobile application and is ready to consume Project.API. If, I have not created separate View Model and DTOs, I should be exposing my ViewModels to the client (mobile application) which is not advisable as it may contain sensitive fields that should be kept private.
  • Separation of Concerns: Keep your DTOs only to pass data and for any other process witihin the application, use ViewModels. Maintain the separation of concerns principle.

These are few points I can think of related to your question.

Latimer answered 29/5, 2018 at 6:7 Comment(0)
R
6

Both are Concrete classes and looks same but their behavior and purpose are different.

We Use DTO because it

  • Removes circular references.

  • Hides particular properties that clients are not supposed to view.

  • Omits some properties in order to reduce payload size.

  • Flattens object graphs that contain nested objects, to make them more convenient for clients.

  • Avoids "over-posting" vulnerabilities.

  • Decouples your service layer from your database layer.

So basically what is the difference

  • DTO's are used to transfer data
  • ViewModels are used to show data to an end user.

The term is simple as your ViewModel is something which changes frequently (on demand).

Say you have a CustomerTable (FirstName, LastName, Age, Gender, DOB)

You will make DTO with all the properties mentioned above. Now if this DTO is being used in one or more layers you can simply refer it to those layers.

But in your UI layer you only want to show customer's FullName , Gender along with Age Calculated.

You will create ViewModel CustomerViewModel(FullName,Gender, Age) with minimized data to use with the probability of frequent changes in future.

  • FullName - FirstName + LastName from DTO
  • Gender - Gender from DTO
  • Age - Calculated from DTO

See more

https://learn.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

Rockweed answered 29/5, 2018 at 6:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.