2

I am new to MVC by Linq. When I am working with Console application its working fine.
When i shift to Mvc Architecture, passing the values from controller to view i am getting error as

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType22[System.String,System.String]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MvcApplication2.Models.Teams]'.

I know i am passing Objects as stringName,String and its expecting 'System.Collections.Generic.IEnumerable how to resolve this kind of issues

This Scenario happen for Multiple groupby and Selectmany in Linq .how to pass the value and get into bind for View . what is the Best approach.

i have put a foreach in Controller and return or else do the foreach iterations in view for selectMany,Groupby,Lookup etc.

Model

public Class Product
{
    public string CategoryName {get; set; }
    public int Productid { get; set; }
    public List<String> Productname { get; set; }

    public static List<Product> GetAllProductName()
    {
        var ListofProducts = new List<Product>
        {
            new Product { CategoryName = "Choclateid", Productid = 1, Productname = new List<string> { "DairyMilkshots", "DairyMilk Silk", "DairyMilkFruitsNuts" }},
            new Product { CategoryName = "Vegetables", Productid = 2, Productname = new List<string> { "Tomoto", "Pototo", "Onion"}},
            new Product { CategoryName  = "Fruits", Productid = 3, Productname = new List<string> {"Apple", "Orange", "Strawberry"}},
        };
        return ListofProducts;
    }
}

Controller

public ActionResult Home()
{
     var ny = Product.GetAllTeamMembers()
                 .SelectMany(x => x.Productname, (category, withProductlist) => 
                                                  new { cat = category.CategoryName, PN = Productname })
                 .ToList();

     return View(ny);
}

View

@model IEnumerable< MvcApplication2.Models.Product>

@{
    ViewBag.Title = "Selectmany";
}

<h2>@ViewBag.Message</h2>
<p>
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
@{  
    foreach(var k in Model)
    {
         @K.CategoryName<br/>
         @k.Productname<br/>
     }                    
 }

Console

var ny = Product.GetAllTeamMembers().SelectMany(x => x.Productname,
                                                            (category, withProductlist) =>
                                                             new { cat = category.CategoryName, PN = Productname };

foreach(var n in ny)
{
   Console.WriteLine(n.cat + "\t" + "-" + n.PN);
}

Output

Choclate -DairyMilkshots DairyMilk Silk DairyMilkFruitsNuts
Vegetables - Tomoto,Pototo,Onion
etc

ekad
  • 14,436
  • 26
  • 44
  • 46
k.nisha Cuty
  • 35
  • 1
  • 10
  • In Console i am iterating underthat action to view in console window.in mvc multiple iteration we need to do means do it in controller or else in view . which is best? – k.nisha Cuty Oct 14 '15 at 18:36
  • Why the `new { cat = category.CategoryName, PN = Productname }`? – haim770 Oct 14 '15 at 18:43
  • here category name store in cat and Product list in PN , that means cat i get choclates in PN result have collections after that i have iterate and get the list of values. – k.nisha Cuty Oct 14 '15 at 19:02

2 Answers2

1

The problem is that your view is set to handle an explicit type:

@model IEnumerable< MvcApplication2.Models.Product>

But the LINQ method does not return a type of Product. You're actually returning an anonymous type with this portion of the LINQ statement:

(category, withProductlist) => new { cat = category.CategoryName, PN = Productname })

The new keyword helps identify that. Your console application works b/c the anynomous object has properties for PN and CategoryName but does not explicitly need a certain type.

Does that make sense?

As has been suggested, you should just pass in the values from the call Product.GetAllTeamMembers() to your view. Your view should then assign the values for the type. For example,

Controller:

public ActionResult Home()
{
   var ny = Product.GetAllTeamMembers();

   return view(ny);
}

View @model IEnumerable< MvcApplication2.Models.Product>

@{  
  foreach(var k in Model)
  {
     @K.CategoryName<br/>
     @k.Productname<br/>

  }                    

} }

EDIT

The best way to do what you want is to create a view model to contain the flattened information. This gives you the shape of the data as you want and allows you to use the model in your controller.

New View Model

public class ProductViewModel
{
    public string CategoryName { get; set; }
    public string ProductName { get; set; }
}

Controller Logic

var ny = Product.GetAllProductName()
.SelectMany(x => x.Productname, (category, withProductlist) =>
    new ProductViewModel
    {
        CategoryName = category.CategoryName,
        ProductName = withProductlist
    });

The View

@model IEnumerable<ProductViewModel>

The important part is in the select many clause, you're casting to a known type (ProductViewModel) instead of an anonymous type.

Derek Van Cuyk
  • 953
  • 7
  • 23
  • The short answer is that you can't if you want to define a model on the view. You have to use a known type and an anonymous type is not known. Some workarounds could be setting the data in ViewData (which seems somewhat less desirable) or possibly using a dynamic object. – Derek Van Cuyk Oct 14 '15 at 19:07
  • problem is here i am passing anonymous type i dont know how to get in view , and i will get the result when pass to the object and iterate it in view and get the result ,by using selectmany lamda expression how to do it in view .because i don't want to iterate in view . – k.nisha Cuty Oct 14 '15 at 19:14
  • check out this thread: http://stackoverflow.com/questions/8820356/dynamic-type-in-mvc-view – Derek Van Cuyk Oct 14 '15 at 19:14
  • yes i understood , for this kind of scenario i have to create a separate class and set the property whatever we are passing and store in that and bind to view right.. – k.nisha Cuty Oct 14 '15 at 19:40
  • If you think this fixes your problem, mark it as the answer please – Derek Van Cuyk Oct 14 '15 at 19:50
0

Just a fetch a list of Product and take it to view then use the joined table like Product.Cateogry and loop in inner table.

Varun Vasishtha
  • 461
  • 2
  • 9