WebAPI - Return models vs entity and partial class with meta data Wanted some opinions on something I have been working with, I've tried a few ways of structuring the way I retrieve and return data to my WebAPI, and I'm pretty happy with what I have so far, but I was looking for a comparison of the pro's and con's of using models vs entities for returning data on the WebAPI.

In my opinion, from what I've seen, adding a model factory and returning models is good because you get control over what your object looks like, but it does mean you now have to map the entities to that model somewhere, increasing the code you have to write, particularly if you have a lot of entities.

On the other hand, having partial classes of the generated objects allows me the same extensibility, and by adding a meta data class using MetadataType(typeof(typename)), I am able to decide what will be serialized and how they are built, giving me full control again over the structure, and being able to extend it when I want to, rather than having to for every entity.

So, if I can get the same benefits with partials and metadata, without the additional code in mapping to models, what are other downsides, how come this approach is not as common? I mean, if I wanted I could do the mapping this way too, without the need for any factories to do the mapping, just by attributing the fields to be ignored and creating new ones with Get/Set to point to the original property.

An example:

Generated by T4 template:

 public partial class FileHeader : BaseEntity
 {
    public FileHeader()
    {
        this.FileVersionSubs = new HashSet&lt;FileVersion&gt;();
    }

    public int FileId { get; set; }
    public string Name { get; set; }
    public string Caption { get; set; }

    public virtual ICollection&lt;FileVersion&gt; FileVersionSubs { get; set; }
 }


The partial I make:

[MetadataType(typeof(FileHeaderMetaData))]
public partial class FileHeader
{        
    // Additional fields go here
}


Metadata file:

public class FileHeaderMetaData
{
    // Any attributes for existing fields here, eg:
    [MyCustomAttribute]
    public int FileId { get; set; }
}


If I were to approach this from a Model point of view, I would be repeating the same properties for every class I generate and wanted to return as well as mapping them, rather than the ones I explicitly want to change or hide.

Thoughts, feelings and suggestions welcome!
No matter how simple I think my application is going to be, I always end up separating my viewmodels from my entities. Not only do I always encounter at least one case where the apparent convenience of any other approach makes it very unwieldly for me to finish a feature, but it's also good to practice loose coupling between your views and your domain.

Say you're using entities with partial classes directly in your views, and the same entity is used in multiple views. Now you have a new feature that requires a change to your entities. How do you know it won't break your existing views? The compiler won't catch it, unless you have an automated suite of UI tests, you'll need to remember to manually test every screen again.

Instead, if you create one viewmodel per view, you get the following advantages:


Each viewmodel can be constructed to meet the needs of a single view. Don't need to some properties of an entity? Leave it out of the viewmodel! Want to include a few extra properties? Throw them in! Want to flatten out some entity hierarchy because it will be easier to display? Do it! 
Some (but not all) breaking changes you make to your entities will now be detected by your compiler. Even if you have unit tests (and you should), this is a nice reminder. 
Factories are much easier to test than views.


In summary, the viewmodel should be the simplest representation of what the view needs, and no more. This decouples your entities from your views as well as decouples your views from each other. It also places mode code where it can be easily tested and maintained. It is a little more work initially but a lot less work in the long run.