0

I have a viewmodel that needs to be populated with data from an entity

I call this method within my controller

public AssessmentResponseVM ConfigureAssessmentViewModel(AssessmentResponseVM model)
{
    if (model.AssessmentID != null)
    {
        model.Questions = getQuestionAndAnswerList(model.AssessmentID);
    }else
    {
        model.Questions = getQuestionAndAnswerList(null);
    }

    return model;
}

It basically retrieves a list of questions and answers for the supplied assessment and assigns them to a property of the viewmodel. Where should this ConfigureAssessmentViewModel method live? At the moment it is sat in my controller but i'm not sure I like it there. Should it sit in the viewmodel class or elsewhere?

Craig W.
  • 17,838
  • 6
  • 49
  • 82
totalitarian
  • 3,606
  • 6
  • 32
  • 55
  • Too opinion based to be suitable a suitable question for SO. Since the mapping is likely to be only applicable for the controller, then a private method in the controller would be fine, as would be moving it to a separate service. But it should not be in your view model class - that would make your code impossible to unit test without injecting the context into the view model. Your view models should have no knowledge of the associated data models (and vice versa) –  Nov 15 '16 at 01:41

2 Answers2

0

In this case you should just keep this logic in your controller and return an Enumerable of questions:

var questionsAndAnswersList = getQuestionAndAnswerList(model.AssessmentID);

Also note that you are checking for a null AssessmentID but then passing null into getQuestionAndAnswerList anyway.

then your View should use

@model IEnumerable<Question>

You may also want another view here that knows how to display only questions. See this other question on display/editor templates.

getQuestionsAndAnswerList most likely belongs in a Service/Business logic class that knows how to access the data and translate it into something the controller knows how to use. How you separate your ViewModel classes and Service classes really depends on the size of your application and preference.

Community
  • 1
  • 1
AJ X.
  • 2,729
  • 1
  • 23
  • 33
0

A good answer would be quite exhaustive, but basically what you have here is what is part of an object mapping layer. I've seen lots of different architectures that handle this differently. Usually the best thing is to be consistent.

For me, because my business models and view models are two different structures, and view models are tailored highly to a view, or sometimes a handful of views in a controllers, then the controller is responsible for populating the view model from the business model. This is because my approach usually involves a data access layer, business layer, and view layer(consisting of controller, view model, view).

There is no business logic in my controllers, and so they are very thin, and all they are really responsible for is calling into the business layer, retrieving business models, and then populating view models with data from the business layer.

The controller is sort of a glue between the UI and the business layer.

Therefore, in this case if I had a function like this that did something as simple as setting some data on the ViewModel, and it for some reason needed to be reused by multiple controller actions, then I'd just make it a private function of the Controller.

If you were working with a different architecture, that might not be appropriate. I've seen cases where the business layer returned ViewModels instead of business models, and so that mapping occurred in the business model.

If you were working with an existing architecture, I would put that code as a private function in the same class that creates the view model initially, i.e. the class containing new AssessmentResponseVM(...

AaronLS
  • 37,329
  • 20
  • 143
  • 202