Search code examples
asp.net-mvc-3razorseparation-of-concerns

ASP.NET MVC 3: Using Enumerable extension methods in the view


Given the following Razor Partial View and understanding that Product is an NHibernate mapped object so the calls to IEnumerable here will fire database queries (when not cached).

Is this bad practice? Should I be providing a flatter view of my data for this view so that I can make these calls in my controller/business logic?

@model IEnumerable<MyProject.Data.Models.Product>
<table>
    <tr>
        <th></th>
        <th>Total Orders</th>
        <th>Fulfilled</th>
        <th>Returned</th>
        <th>In stock</th>
    </tr>
    @foreach (var product in Model) { 
        <tr>
            <td>
                @Html.ActionLink(product .Name, "Detail", "Product", new { id = product.Id }, null)
            </td>
            <td>
                @product.Orders.Count
            </td>
            <td>
                @product.Orders.Where(x=>x.Fulfilled).Count()
            </td>
            <td>
                @product.Orders.Where(x=>x.Returned).Count()
            </td>
            <td>
                @(product.Stock.Count - product.Orders.Count)
            </td>
        </tr>
    }
</table>

Solution

  • Is this bad practice?

    Yes.. In fact it's breaking the MVC pattern - the View's should not call back through the model, only receive in order to do it's sole job: rendering HTML.

    If you need additional information than just the one entity, populate a ViewModel with all the information you need, then pass that to your View.

    Also, don't loop through the IEnumerable in the model, use a Display Template:

    @Html.DisplayForModel()

    The advantage of this is no explicit loop, taking advantage of MVC conventions, and adhering to model hierachy when model binding.