I am trying to allow dynamic filtering of a view in MVC.
after a bit of faffing I tried this...which sort of worked
The select control extracts a unique set of values from the model to make the options
foreach (var i in Model.Select(s => new{s.ListId, s.ListName}).Distinct())
{
<option value="@i.ListId">@i.ListName</option>
}
This works fine until you have filtered. Once you have run the filter you have only the option that you already filtered (ie if you chose to filter on ListID1, the only select option is ListID1)
so...
in the controller, I have set up a list from the unfiltered model and shoved that in ViewBag
public async Task<IActionResult> Index(int? ListID)
{ var listoflists = (from l in _context.UgPoints
select new { l.ListId, l.ListName } ).Distinct();
ViewBag.listoflists = listoflists;
then in the view I look at that
var lst = ViewBag.listoflists as IEnumerable<Draco2018MVC.Models.UgPoints>;
{
foreach (var l in lst)
{
<option value="@l.ListId"> @l.ListName</option>}
}
but the lst variable is always null.
I am assuming that I have missed something fundamental, but I cannot see what.
Anybody able to suggest either
a better way to get a unique set of values to filter the rest of the page
or
what I am doing wrong with the viewbag
thanks
Your current controller code is generating a collection of annonymous items with ListId
and ListName
properties.
Specifically this projection part of your line statement
select new { l.ListId, l.ListName }
In your view, you are trying to cast it to a collection of your class, and it is failing, hence you get lst as null.
You may create a list of SelectListItem
object from your LINQ statement and set that to view bag.
var listoflists = (from l in _context.UgPoints
select new SelectListItem {
Value= l.ListId.ToString(),
Text = l.ListName }
).Distinct();
ViewBag.listoflists = listoflists;
Now in your view, you may even use the DropDownList helper method
@Html.DropDownList("ListID",ViewBag.listoflists as IEnumerable<SelectListItem>)
Keep in mind that, you are trying to call Distinct()
method on a collection of UgPoints
objects. When the type is a reference type, you probably want to override the Equals method of that to make it easier for the Distinct method code.
Use of Distinct with list of custom objects
Another option is get data from a source which does not have duplicate data. Perhaps a lookup table which has unique records. You probably need to make adjustments to your db design for that.