2

I am creating a filter view to find records. This example on SO helps, but does not mention how handle the (Filtered) View.

The err below is because, the actions returns a List<ProductViewModel>, and it Errors/complains that the View is using a SearchViewModel, I need to this POST the searchmodel/variables, butGET back the list/results model

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ViewModels.ProductVM]', but this dictionary requires a model item of type 'ViewModels.SearchModel'.

Issue/Question: Since there are two models, the SearchViewModel passed to the controller & the ProductViewModel returned as a result, which model should be strongly typed to the view? and How can I create the view to handle both SearchModel & ProductModel If I stronglyType ProductVM, then I loose the submitform from the SearchVM.

I create the SearchView as the mainview, & the _ResultsPartialView as a partialView, is this wrong?

public ActionResult Index(SearchModel searchModel)
{
    var filteredProdVMList = _Repository.GetFilteredProducts(searchModel);
    return View(filteredProdVMList);
}

public class ProductVM
{
    public int Id { get; set; }
    public int Price { get; set; }
    public string Name { get; set; }
    // implicit const... blah.. removed
}

public class SearchModel
{
    public int? Id { get; set; }
    public int? PriceFrom { get; set; }
    public int? PriceTo { get; set; }
    public string Name { get; set; }
}
Transformer
  • 6,963
  • 2
  • 26
  • 52
  • 1
    `SearchModel` needs to contain a property `IEnumerable`, and you view uses `@model SearchModel` (and you probably should be making a GET, rather than a POST when you submit) –  Jan 06 '18 at 07:30
  • I compsed a new VM with `List` & `SearchModelVM` .. I got this erro.. _The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ViewModels.ProductVM]', but this dictionary requires a model item of type `ViewModels.Search..VM'._ – Transformer Jan 06 '18 at 07:58
  • 1
    To understand that error, refer [this answer](https://stackoverflow.com/questions/40373595/the-model-item-passed-into-the-dictionary-is-of-type-but-this-dictionary-requ). But you did not seem to understand my first comment. Your existing `SearchModel` just needs an additional property `public IEnumerable Products { get; set; }` and you return just `SearchModel` back to your view (and populate `Products` based on the filters and use a `foreach(var product in Model.Products)` in the view –  Jan 06 '18 at 08:01
  • 1
    You have not shown the view or the other controller method so hard to give a concise answer –  Jan 06 '18 at 08:04
  • @StephenMuecke I added the view code.. cleared out some of the extra stuff. While searching I saw previous answer where you were appending invoices... but I keep getting the error above. – Transformer Jan 06 '18 at 08:22
  • The only controller method you have shown is `Index()` which is for an `Index.cshtml` view (is that the view you have shown?). –  Jan 06 '18 at 08:24
  • 1
    Basically you controller method should be populating the `products` property - e.g. `searchModel.products = _Repository.GetFilteredProducts(searchModel);` and then `return View(searchModel);` and you really only need one method and then change your form to `@using (Html.BeginForm("Index", "yourControllerName", FormMethod.Get))` –  Jan 06 '18 at 08:29
  • Thanks that fixed it! I made the update in the model but forgot in the action/controller, so I was missing the update `filter.products = filteredProdList ;`. Can you tell me how to append the async partialview results as HTML table, I cannot get it work – Transformer Jan 06 '18 at 08:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/162646/discussion-between-stephen-muecke-and-transformer). –  Jan 06 '18 at 08:37
  • @StephenMuecke I can mark as answer, just post a one line text as answer :) – Transformer Jan 08 '18 at 06:21

1 Answers1

3

You need to modify your SearchModel to include a collection property for the products

public class SearchModel
{
    public int? PriceFrom { get; set; }
    public int? PriceTo { get; set; }
    ....
    public IEnumerable<ProductVM> Products { get; set; } // add
}

then you return just SearchModel to your view

public ActionResult Filter(SearchModel filter)
{
    filter.Products = _repository.GetFilteredProducts(filter);
    return View(filter);
}

and your view will be

@model SearchModel
....
@using (Html.BeginForm("Filter", "yourControllerName", FormMethod.Get))
{
    @Html.LabelFor(m => m.PriceFrom)
    @Html.EditorFor(m => m.PriceFrom)
    @Html.ValidationMessageFor(m => m.PriceFrom)
    ... // other form controls for properties you want to filter the results on
    <input type="submit" value="Filter" />
}
@Html.Partial("_ResultsPartialView", Model.Products)