Can you help with this MVC ViewModel issue?
Asked Answered
W

2

0

I have a problem with an MVC view that I just cannot seem to solve. Here it is.

1) I have an index view that displays a list of retailers with data from the retailers table. So far so good.

2) I also want to include the retailer categories for each retailer which are stored in a RetailersCategories table where each retailer can have multiple categories

I have tried a few things but cannot seem to make this work. The closest I came to what I wanted was using a view model. I have included the code below.

I actually get the right data back but I get all of the retailer records and then all of the category records.

What I need is one retailer record at a time with all of the categories that relate to that retailer.

Can anyone show me how I can achieve this?

//Controller   

public ActionResult Index(int? page, int country)
{
    var viewdata = new retailersIndexViewModel(_retailerRepository.GetAllRetailersByCountry(country),  _retailerRepository.GetRetailerCategories());
    return View(viewdata);       
}

// ViewModel

public class RetailersIndexViewModel
{        
    public IEnumerable<RetailersShipping> RetailerShipping { get; set; }
    public IEnumerable<RetailersCategory> RetailerCategories { get; set; }

    public RetailersIndexViewModel(IEnumerable<RetailersShipping> retailer, IEnumerable<RetailersCategory> retailercategory)
    {
        this.RetailerShipping = retailer;
        this.RetailerCategories = retailercategory;
    }
}


//IndexView

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Inner.Master" Inherits="System.Web.Mvc.ViewPage<RetailersIndexViewModel>" %>

<% Html.RenderPartial("RetailerSummaryPartial", this.ViewData.Model.RetailerShipping); %>
<div id="retailer_index_categories">

<%
    foreach (RetailersCategory category in ViewData.Model.RetailerCategories) 
    {%>
        <% Html.RenderPartial("RetailerCategoryPartial", category); %>
    <% } %>


// RetailerSummaryPartial

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<RetailersShipping>>" %>

<div id="retailer_partial_summary">
<% foreach (var retailer in Model)
{ %>
    <div id="retailer_index_image">
        <img src="<%=Html.Encode(retailer.Retailer.Country.Image) %>" title="<%= Html.Encode(retailer.Retailer.Name) %>>" alt="<%= Html.Encode(retailer.Retailer.Name) %>" class="main-image" />
        <br />
    </div>
    <div id="retailer_index_logo">
        <img src="<%=Html.Encode(retailer.Retailer.Logo) %>" title="<%= Html.Encode(retailer.Retailer.Name) %>>" alt="<%= Html.Encode(retailer.Retailer.Name) %>" class="main-image" />
    </div>
    <div id="retailer_index_name_comment">
        <%= Html.Encode(retailer.Retailer.Name)%><br />
        <span><%if (retailer.Retailer.CountryId == retailer.Retailer.CountryId) %>
                <%= Html.Encode(retailer.Retailer.LocalComment)%>
                <%= Html.Encode(retailer.Retailer.IntComment)%>
        </span>
    </div>

<% } %>
</div>


//RetailerCategoryPartial

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<RetailersCategory>" %>
<div id="retailer_index_categories">
    <%= Html.Encode(Model.Category.CategoryName) %>
</div>
Wastage answered 30/11, 2010 at 21:40 Comment(3)
Are you by any chance using Entity Framework 4?Kagera
Are looking for guidance on how to structure your ViewModel or how to hack it together with the current view model? Ideally you would simply have a categories list on each retailer...instead of trying to join the categories in the view...Geri
hi dotjoe. happy to go with the categories list solution if that works. can you please explain a bit more to me on that?Wastage
Z
3

I'd refactor your view models. If you're going to be representing a collection within a collection it's best your view models reflect that.

public class RetailersIndexViewModel {

    public IEnumerable<RetailersShippingViewModel> RetailerShippings { get; set; }

    public RetailersIndexViewModel(IEnumerable<RetailersShipping> shippings)
    {
        this.RetailerShippings = shipping;
        foreach( var shipping in shippings)
        {
            shipping.RetailerCategories = shipping.Categories // assuming Categories is referenced in your Retailer Shipping class;
        }
    }
}

public class RetailerShippingViewModel {

    public IEnumerable<RetailersCategory> RetailerCategories { get; set; }

    public RetailersIndexViewModel(IEnumerable<RetailersCategory> retailercategories)
    {
        this.RetailerCategories = retailercategories;
    }
}

and render it like so

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Inner.Master" Inherits="System.Web.Mvc.ViewPage<RetailersIndexViewModel>" %>

   <% foreach(var shipping in Model.RetailerShippings)
      {
          Html.RenderPartial("RetailerSummaryPartial", shipping); 
      }%>

call this in your RetailerSummaryPartial instead of the index view

<%
    foreach (var category in ViewData.Model.RetailerCategories) 
       {%>
    <% Html.RenderPartial("RetailerCategoryPartial", category); %>
    <% } %>
Zacatecas answered 30/11, 2010 at 23:37 Comment(0)
F
2

Try to use one of ORM frameworks (such as NHibernate, ADO.NET Entity framework, Linq to SQL,...) After that making valid mapping db schema with your entity, and then you can get one category have many retailer, build the ViewModel and binding to View. If you want to make it complex, can customize the Model Binder for binding between View and Controller. IMHO.

Fokos answered 30/11, 2010 at 21:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.