So lets say I have two models:
Thingy and Status. Thingy
has a Status
, and Status has many Thingies. It's typical "Object and Object type relationship".
I have a view where I just want the number of thingies in each status. Or basically a list of Status.Name and Status.Thingies.Count. I could do exactly this, but is the "right" thing to do to create a view model in the form:
ThingiesByStatusViewModel
-StatusName
-StatusThingiesCount
and hook it up with something like AutoMapper.
For such a trivial example, it probably doesn't make much of a difference, but it would help me understand better the proper 'separation of concerns'.
Should I use a viewmodel here?
Is this a rhetorical question?
Your view model would look exactly as you propose and it is perfectly adapted to what you are trying to display here:
public class ThingiesByStatusViewModel
{
public string StatusName { get; set; }
public int StatusThingiesCount { get; set; }
}
and then your controller would return an IEnumerable<ThingiesByStatusViewModel>
. Then in your view you could simply use a display template:
@Html.DisplayForModel()
and the corresponding display template (~/Views/Shared/DisplayTemplates/ThingiesByStatusViewModel.cshtml
):
@model AppName.Models.ThingiesByStatusViewModel
<div>
<span>StatusName: @Model.StatusName</span>
<span>Number of thingies: @Model.StatusThingiesCount</span>
</div>
Now let's look at the mapping layer. Suppose that we have the following domain:
public class Thingy
{ }
public class Status
{
public string StatusName { get; set; }
public IEnumerable<Thingy> Thingies { get; set; }
}
and we have an instance of IEnumerable<Status>
.
The mapping definition could look like this:
Mapper
.CreateMap<Status, ThingiesByStatusViewModel>()
.ForMember(
dest => dest.StatusThingiesCount,
opt => opt.MapFrom(src => src.Thingies.Count())
);
and finally the controller action would simply be:
public ActionResult Foo()
{
IEnumerable<Status> statuses = _repository.GetStatuses();
IEnumerable<ThingiesByStatusViewModel> statusesVM = Mapper.Map<IEnumerable<Status>, IEnumerable<ThingiesByStatusViewModel>>(statuses);
return View(statusesVM);
}
I, personally, don't like to send non-trivial types to the view because then the person designing the view might feel obligated to start stuffing business logic into the view, that that's bad news.
In your scenario, I'd add a StatusName property to your view model and enjoy success.
Yes, you should use VM.
Guess, You have time for some experiments, so try to do it in a proper way. Next time, you will do that much quicker.
If current example is trivial - then it will be easier to get practice session.
Also, In future your application will grow up and you never know when you need to extend it. So implementing it in proper way provide you a good maintainability for future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With