0

I'm Completely new in ASP.net MVC

I have two model first is category

public class Category
{
    public virtual int Id { get; set; }
    [Required]
    public virtual string CategoryName { get; set; }
    public virtual List<SubCategory> SubCategories { get; set; }

}

and next subcategory model:

public class SubCategory
{
    public virtual int Id { get; set; }

    public virtual int CategoryId { get; set; }
    [Required]
    public virtual string SubCategoryName { get; set; }
    public virtual Category Category { get; set; }
    public virtual List<Question> Questions { get; set; }

}

I need to have a list of my categories and also a list of subcategories both in my view so this is my view model

public class CategorySubCategoryViewMoel
{
    public ICollection<Category> Category { get; set; }
    public SubCategory SubCategory { get; set; }


}

and here is my view

@model FinalSearch5.Models.CategorySubCategoryViewMoel
 <ul>
   @foreach (var category in Model.Category)
   {
     <li>@category.CategoryName</li>
   }
 </ul>

here is my controller

    public ActionResult Index()
    {
        var cats = db.Categories.ToList();
        return View(cats);
    }

It's not implementing completely yet but until here there is an Error

The model item passed into the dictionary is of type 'System.Collections.Generic.List1[FinalSearch5.Models.Category], but this dictionary requires a model item of type 'FinalSearch5.Models.CategorySubCategoryViewMoel'.`

Appreciate if help me what is the problem thank you.

neda Derakhshesh
  • 1,103
  • 2
  • 20
  • 43
  • Possible duplicate of [Two models in one view in ASP MVC 3](http://stackoverflow.com/questions/5550627/two-models-in-one-view-in-asp-mvc-3) – Aravind Jul 24 '16 at 08:56
  • 2
    The error message is self explanatory (your view expects `CategorySubCategoryViewMoel` but your passing it `List` But `Category` contains a collection of `SubCategory` so why do you need a view model with 2 separate collections - surely you would want to display each category, and for each category, its collection of `SubCategory` (i.e. nested `foreach` loops) –  Jul 24 '16 at 09:05
  • @Aravind thank you.I checked some of related questions. my problem is that I have a collection of my categories in view model. if I omit this collection I have Compilation Error in this line `@foreach (var category in Model.Category)` – neda Derakhshesh Jul 24 '16 at 09:06
  • 1
    You don't necessarily need a view model if the view is for display only (although its still good practice to use one). The view can be `@model List –  Jul 24 '16 at 09:14
  • its not just for display I want to use ajax on it and also I need to learn it better , but you suggest me an amazing way . I implement my model in view this way `@model IEnumerable ` but nested foreach said `it does not contain a public definition for GetEnumrator` – neda Derakhshesh Jul 24 '16 at 09:39
  • 1
    By _display only_, I meant that you are not editing properties of `Category` or `SubCategory` in the view (in which case a `foreach` loop would never have worked anyway). –  Jul 24 '16 at 09:46
  • 1
    And that should have read `@foreach(var subCategory in category.SubCategories) { ` –  Jul 24 '16 at 09:47
  • @StephenMuecke thank you it works fine. really thank you. I don't know should I ask you to answer or not but my problem solved .thanks again – neda Derakhshesh Jul 24 '16 at 09:55

1 Answers1

2

You view expects a model which is typeof CategorySubCategoryViewMoel but in the Index() method, you return a model which is List<Category>. In order for it to work, you could change the method to

public ActionResult Index()
{
    var model = new CategorySubCategoryViewMoel
    {
        Category = db.Categories.ToList()
    }
    return View(model );
}

Note that the property is a collection, so its name should be pluralized, and need only be IEnumerable i.e. public IEnumerable<Category> Categories { get; set; }

However its unclear what the purpose of your view model is. Its only other property is public SubCategory SubCategory { get; set; } and you never assign a value to it, or use it in the view. You code could use your current Index() method and then the view would be

@model List<Category>
<ul>
    @foreach(var category in Model)
    {
        <li>
            @category.CategoryName
            <ul>
                @foreach(var subCategory in category.SubCategories)
                {
                    <li>@subCategory.SubCategoryName</li>
                }
            </ul>
        <li>
    }
<ul>