Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set the model depending on what it is expecting in view

The goal

Change the model depending on what it is expecting.

The problem

I have a method in my ProductsControllercalled Category. When someone request this method, two things can happen: if the parameter passed to the method is different than Daily-Offers, then one type of list is passed to View. If the parameter passed to the method is equal to Daily-Offers, then another type of list is passed to View.

To better comprehension, see:

[HttpGet]
public ActionResult Category(string categoryName = null)
{
    int? categoryId = categoryName != "Daily-Offers" ? 
                      Convert.ToInt32(Regex.Match(categoryName, @"\d+").Value) :
                      (int?)null;

    if (categoryName == "Daily-Offers")
    {
        var productsList = Products.BuildOffersList();
        ViewBag.Title = String.Format("Today's deal: ({0})", DateTime.Now);
        ViewBag.CategoryProductsQuantity = productsList.Count;
        ViewBag.CurrentCategory = "Daily-Offers";
        return View(productsList);
    }
    else if (Regex.Match(categoryName, @"\d+").Success && 
             String.Format("{0}-{1}", 
             categoryId, 
             CommodityHelpers.UppercaseFirst
                (CommodityHelpers.GenerateSlug
                     (Categories.GetDetails((sbyte)categoryId).Category_Name))) 
            == categoryName)
    {
        ViewBag.Title = Categories.GetDetails((sbyte)categoryId).Category_Name;
        ViewBag.CategoryProductsQuantity = 
        Categories.GetDetails((sbyte)categoryId).Category_Products_Quantity;
        ViewBag.CurrentCategory = 
           CommodityHelpers.UppercaseFirst(CommodityHelpers.GenerateSlug
           (Categories.GetDetails((sbyte)categoryId).Category_Name));
        return View(Products.BuildListForHome(categoryId, null));
    }
    else
    {
        return View("404");
    }
}

As you can see, the view should be prepared to receive IList<Offers> or/and IList<NormalProducts>and I do not know how to do this.

What I have already tried

Something like this:

@model if(IEnumerable<BluMercados.Models.Data.getProductsListForHome_Result>) 
       ?: (IEnumerable<BluMercados.Models.Data.getProductsInOfferList_Result>);

But, of course, no success. Just to illustrate.

like image 812
Guilherme Oderdenge Avatar asked Jun 14 '13 20:06

Guilherme Oderdenge


1 Answers

A view should really only have one model, so trying to make a view consume two different models, while doable, shouldn't be done.

Instead, you can create different views. Say you create a new view for DailyOffers, which takes IEnumerable<Offers> as its model.

You can then user an overload of View() to specify which view to return:

return View("DailyOffers", productsList);

However, instead of doing this, would it make more sense to redirect to a different action in the case of DailyOffers? So, you have a new action:

public ActionResult DailyOffers(...)

and instead of return View(productsList) you do:

return RedirectToAction("DailyOffers");

This all assumes that the models are sufficiently different from one another. If they are similar, using the Interface solution as suggested by p.s.w.g. would make more sense.

like image 69
Matthew Jones Avatar answered Nov 14 '22 21:11

Matthew Jones