3

when do you think is it better to use ViewData over a view model?

I have the same exact partial view in a couple of main views. I'd like to control how a partial view is rendered but I'd also prefer the partial view to accept only a view model which is a collection of records, just a pure IEnumerable<> object. I'd rather avoid to send the full view model object from a main view because it also contains a lot of different properties, objects, that control paging, sorting, filtering etc.

Therefore the question is if I should create another view model for the partial view or is it ok to use ViewData? I've read soemwhere that using ViewData is a very bad practice.

With View Data, I could simply pass require details like this:

@{
    ViewDataDictionary vd = new ViewDataDictionary
    {
        new KeyValuePair<string,object>("WithDelete", Model.WithDelete),
        new KeyValuePair<string,object>("WithRadarCode", Model.WithCode)
    };
}

// ...

@if (Model != null) {
    Html.RenderPartial("_ListOfRecordingsToRender", Model.recordingViewModel, vd);
}

At the moment, it would be sorted out.

My worry is that currently this *.recordingViewModel has plenty of different variations in my project, because of different models for creating / editting, listing, shoing details of a record etc. I feel like it may start to be too messy in my project if I make view model for each action.

What do you think. Please could you advice on that particular problem. Thanks

Celdor
  • 2,437
  • 2
  • 23
  • 44

1 Answers1

7

I think you should stick to using a ViewModel, your ViewModel is the class that defines your requirements for the view.

My reason behind this is that in the long run, it will be a lot more maintainable. When using ViewBag it's a dynamic class so in your views you should be checking if the ViewBag property exists (And can lead to silly mistakes like typo's) e.g.:

if(ViewBag.PropertyName != null)
{
    // ViewBag.PropertyName is a different property to ViewBag.propertyName
}

This type of code can make your View's quite messy. If you use a strongly typed model, you should be able to put most of the logic in your controllers and keep the View as clean as possible which is a massive plus in my books.

You also will also end up (if you use ViewBag) attempting to maintain it at some point and struggle. You are removing one great thing about C#, it's a strongly typed language! ViewBag is not strongly typed, you may think you are passing in a List<T> but you could just be passing a string.

One last point, you also will lose out on any intellisense features in Visual Studio.

I feel like it may start to be too messy in my project if I make view model for each action.

Wont it just be as messy in your controllers assigning everything to a ViewBag? If it was a ViewModel you could send it off to a 'Mapping' class to map your DTO to your View.

Instead of this:

// ViewModel
var model = new CustomViewModel()
{
    PropertyOne = result.FirstResult,
    PropertyTwo = result.SecondResult,
}
//ViewBag
ViewBag.PropertyOne = result.FirstResult;
ViewBag.PropertyTwo = result.SecondResult;

You could do this:

var mapper = new Map();
var model = mapper.MapToViewModel(result);

*You would obviously need to provide an implimentation to the mapping class, look at something like Automapper

I'd also prefer the partial view to accept only a view model which is a collection of records, just a pure IEnumerable<> object. I'd rather avoid to send the full view model object from a main view because it also contains a lot of different properties, objects, that control paging, sorting, filtering etc.

That is fine, just create a view model that has a property of IEnumerable<T>. In my opinion you should try and use a strongly typed ViewModel in all of your scenarios.

Jamie Rees
  • 7,973
  • 2
  • 45
  • 83
  • 1
    I agree. Using viewmodels, overall, is my favourite way also. – Jason Evans Jul 27 '15 at 08:00
  • Good answer, viewmodels all the way. – Ric Jul 27 '15 at 08:21
  • ViewBag might be useful in some scenarios, but I would prefer to avoid it. You know as soon as you see `ViewBag` uses it's an instant code smell. – Jamie Rees Jul 27 '15 at 08:22
  • @JamieRees Hi. Thanks for a quick answer. OK i am going to change the code. I did not follow this: "you could send it off to a 'Mapping' class to map your DTO to your View". I don't understand what it means to map DTO and what 'mapping' is. I probably missing simething simple here ... – Celdor Jul 27 '15 at 08:36