1

I have the following Entities and ViewModel (some properties removed for clarity):

Ticket:

public class Ticket
{
    [Key] 
    public int ID { get; set; }

    public string Comment { get; set; }

    //Navigation Property
    public virtual ICollection<Attachment> Attachments { get; set; }
}


Attachment:

public class Attachment
{
    [Key]
    public int ID { get; set; }

    //Foreign key for Ticket
    public int TicketID { get; set; }

    public byte[] FileData { get; set; }

    public string FileMimeType { get; set; }

    //Navigation Property 
    public virtual Ticket Ticket { get; set; }
}


TicketViewModel:

public class TicketViewModel
{
    //Default constructor
    public TicketViewModel()
    {

    } 

    //Constructor with parameter
    public TicketViewModel(Ticket ticket)
    {
        Ticket = ticket;
        Attachment = new Attachment();
    }

    public Ticket Ticket { get; set; }

    public Attachment Attachment { get; set; }  

    public virtual ICollection<Attachment> Attachments { get; set; }              
}


In the Create a new Ticket page, there is also attachment field and multiple attachments can be added to this newly created ticket. For this reason I use TicketViewModel and pass Ticket and ICollection<Attachment> to the controller. On the other hand, I am not sure if I am wrong, because I can pass just 'Ticket' to the controller and create a new instance of TicketViewModel in the controller by passing Ticket model to the constructor of TicketViewModel. In this scenario, what approach should I follow?
Note: I pass IEnumerable<HttpPostedFileBase> to the controller for Attachment data.


Update:

I updated View and pass Model instead of ViewModel as shown below:

View:

@model Ticket
//... some other stuff

And in the controller, I pass the filled Model and new instance of the Attachment Collection to the method in the data layer as shown below.


Controller:

List<FileAttachment> fa = new List<FileAttachment>();
ekad
  • 14,436
  • 26
  • 44
  • 46
Jack
  • 1
  • 21
  • 118
  • 236
  • I'm not sure that I understand what your question is. You seem to be confused with the terms View, Model, and ViewModel. A page is typically going to have both a View and a ViewModel. – Claies Jun 14 '15 at 22:13
  • Actually no, I know what the View, Model and ViewModel is. The problem is that, I was using ViewModel in the Create view and of course pass this ViewModel to the Controller. However, I thought that there is no need to use ViewModel in the Create view and decided to pass Model to the Create View and to the Controller. **At this step**, I need to pass both model data Ticket and Attachment to the Data Layer. In addition to this, I also have to keep Model data filled in the Create view. For this reason I thought that it is good approach to pass this model to the ViewModel's constructor. Any idea? – Jack Jun 14 '15 at 22:22
  • @Claies Any idea? If there is anything to be clarified, please do not hesitate to ask me again. Thanks in advance... – Jack Jun 14 '15 at 22:30
  • 1
    Your title does not make sense; and you still haven't clarified your issue. You don't want to use a ViewModel in the View, but need it in the Controller? It's not called a ControllerModel.... – Claies Jun 14 '15 at 22:31
  • Your not using a true view model. A view model contains only those properties you need or display/edit in the view ( refer [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc)). For your create view, an ID property is not appropriate, neither is a collection of `Attachment`. In your case the view model would contain 2 properties - `string Comment` and `IEnumerable Files` –  Jun 14 '15 at 23:01
  • 1
    And edit your title - I assume you mean _" ..data model or view model"_ –  Jun 14 '15 at 23:12
  • @StephenMuecke Ahh, sorry I corrected the title. Regarding to your comment, I know that ViewModel should contain only the properties I need. however, what is I need all the properties in a model (Ticket) inside the ViewModel? Could it be better to define Ticket model instead of definining all the properties of it? What about the using the constructor in the ViewModel? What is wrong? – Jack Jun 15 '15 at 06:51
  • Claises: Sorry, I edited the title. Have a look at please? – Jack Jun 15 '15 at 06:52
  • Sorry I don't understand your comment. Your `Ticket` data model contains only 3 properties. The `ID` and `Attachments` properties are not required when creating a new `Ticket` so your `CreateTicketVM` should only contain `string Comment` and also `IEnumerable Files` (so you do't need an additional parameter in the POST method) –  Jun 15 '15 at 06:55
  • @StephenMuecke Thanks for reply. I added an Update and for now I send the filled Ticket model (coming from view) and a new instance of attachment model for passing to the method of data layer. Is this final approach true or is there any mistake? – Jack Jun 15 '15 at 09:36
  • 3
    IMHO, you should never use a data model in the view - it should always be a view model. –  Jun 15 '15 at 09:39
  • Do you meant that I should always create a ViewModel even if I need the properties in the Data Model (Data model means the Entity models defined in Data Layer)? Why? – Jack Jun 15 '15 at 09:47
  • @StephenMuecke Any reply pls? – Jack Jun 15 '15 at 10:23
  • @Christof, I have already given you my opinion, which is to use a view model in the view (and in the POST method your map the view model properties to the data model and save the data model). As for why - read the answers in the previous link I gave –  Jun 15 '15 at 10:35
  • @StephenMuecke Many thanks for your nice explanations. I decided to use ViewModel properly under the explanation on [link](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) page that you suggested. On the other hand, I am wondering what if for `Creating/ Editing` a record? In that case should we pass `ViewModel` to the View and return it to the Controller? Or should we use `Domain Model` such a kind of operations? >>> – Jack Jun 15 '15 at 12:36
  • @StephenMuecke >>> Because I always pass Domain model to the **SaveChanges()** method and not sure if it is possible to pass ViewModel? In addition to this, I used Domain Models in my interface definitions and I would prefer to pass `DomainModel` instead of `ViewModel` for `Creating/ Editing` records. What do you think? – Jack Jun 15 '15 at 12:36
  • 1
    @Christof, You need to read my comments and the answers in the link I gave you. You DO NOT pass the view model to `SaveChanges()`. You map the properties of the view model to an instance of domain model and pass the domain model to `SaveChanges()`. I have told you numerous time what I think (and what is considered best practice) but do what you want. –  Jun 15 '15 at 12:42
  • @StephenMuecke Ok, thanks. Actually I had already read your comment and the page you suggested, but "mapping" is the key for me as a last step. I found [this](http://www.edandersen.com/2013/05/30/asp-net-mvc-basics-part-2-viewmodel-to-model-mapping-and-editing/) article for mapping. Many thanks again for your kind helps... Regards. – Jack Jun 15 '15 at 13:04

1 Answers1

1

While the real answer is subjective and based entirely on personal preference, I will give you my answer and reasons.

Passing a so-called View Model is typically better than passing an Entity POCO, due to the fact that the page/forms will likely require more data than is used in the POCO.

In the case you provided I would flatten the classes in a View Model by merging the properties into one class for easy binding, and then create a Process() function to provide the two POCOs I needed. Usually when working complex models the Process() function will return a new Domain Model to save, or accept a Domain Model to edit.

For example, you may want to provide cheap bot protection in the form of an arithmetic problem that wouldn't need to be saved anywhere. Passing a View Model can also limit the exposing of data, in case the person doing the back end stuff is different from the person laying out the Views.

In most cases, though, the POCO can be just fine. I personally tend to pass View Models for complex data, and the actual POCO for small tables, like when the only two columns are a UID and a text field.

Codeacula
  • 2,329
  • 25
  • 30
  • Thanks. I decided to use ViewModel properly under the explanation on [link](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) page that Stephen Muecke suggested. On the other hand, I am wondering what if for `Creating/ Editing` a record? In that case should we pass `ViewModel` to the View and return it to the Controller? Or should we use `Domain Model` such a kind of operations? Because I always pass Domain model to the **SaveChanges()** method and not sure if it is possible to pass ViewModel? – Jack Jun 15 '15 at 12:35
  • In addition to this, I used Domain Models in my interface definitions and I would prefer to pass `DomainModel` instead of `ViewModel` for `Creating/ Editing` records. What do you think? – Jack Jun 15 '15 at 12:35
  • Does the edit answer your questions? :) Like I said, this is all subjective so there's no true answer, just "what works best for this". – Codeacula Jun 15 '15 at 12:47
  • By using View mapper, I return ViewModel to the Controller and map it, then return View to the Database layer. I think it is one of the good option for this scenario. – Jack Jun 19 '15 at 06:43