0

I have an Index (List) View in MVC5, that is populated from a model (Table ICS_Supplies).

I have added a textbox to add search filter for the users, on field ItemDescription (varchar). This works perfectly fine as follows:

View

<form asp-controller="Movies" asp-action="Index">
  <p>
    Search Supplies: <input type="text" name="SearchString">
    <input type="submit" value="Filter" />
  </p>
</form>

Controller

public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
    // Add SearchBox Filter
    var catalogs = supplies.Where(s =>  s.ItemDescription.Contains(searchString ?? string.Empty));

    // Add paging to the search results
    var pageNumber = page ?? 1;
    return View(catalogs.ToPagedList(pageNumber, 10));
}

This works perfectly. If the searchString is null, it brings back ALL results. IF the searchSring has a value, it brings back any results where ItemDescription Cotain the searchString Value.

I am trying to add a radiobutton to the index view so that the user can also filter on the field InvType, which is a char(1) field. It can be F (for Forms) or S (for supplies). So, I set the value of YourRadioButton to F or S depending on which is selected. . . as follows (with new code)

Index

<form asp-controller="Movies" asp-action="Index">
  <div>
    Supplies: @Html.RadioButton("YourRadioButton", "S")
    Forms: @Html.RadioButton("YourRadioButton", "F")
  </div>
  <p>
    Search Supplies: <input type="text" name="SearchString">
    <input type="submit" value="Filter" />
  </p>
</form>

And I update the Controller with additional code, as follows:

public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
    var supplies = db.ICS_Supplies.OrderBy(g => g.ItemDescription).ToList();

    //var supplies2 = supplies.Where(s => s.InvType.Equals(mychoice));
    var supplies2 = supplies.Where(s => s.InvType.Contains(YourRadioButton ?? string.Empty));

    // Add SearchBox Filter
    var catalogs = supplies2.Where(s =>  s.ItemDescription.Contains(searchString ?? string.Empty));

    // Add paging to the search results
    var pageNumber = page ?? 1;
    return View(supplies2.ToPagedList(pageNumber, 10));
}

Now, I receive The following error

System.NullReferenceException

And it is referring to the following line of code (which I added)

var supplies2 = supplies.Where(s => s.InvType.Contains(YourRadioButton ?? string.Empty));

My question(s) are . . . Why does that kick out a NullReferenceException, but the other line works perfectly fine if it is null? And how do I resolve the issue - or is there a better way to add this second filter to my code?

This line works fine, null or not. They are both identical in how they are written, other than the Value of YourRadioButton is used, instead of searchString, and I am using InvType field instead of ItemDescription.

var catalogs = supplies2.Where(s => s.ItemDescription.Contains(searchString ?? string.Empty));

Keep in mind that I am VERY new to both MVC5 and C#, and so explaining why would help me a great deal to progress.

There does not seem to be a lot of information out there, in regards to using radio buttons in MVC5 . . . a rather simple concept in old Asp.net forms.

Marc
  • 3,905
  • 4
  • 21
  • 37
ExecChef
  • 387
  • 2
  • 13
  • 1
    Have you read [this](https://stackoverflow.com/q/4660142/4685428) question? – Aleks Andreev Apr 30 '19 at 19:48
  • @AleksAndreev - I appreciate your reply. I have not yet read that question. However, I have begun now. It is quite lengthy and a bit over my head, but I will certainly see what I can get from it. I am really confused how to very similar lines of code behave completely differently. One works just fine with nulls, and the other does not. Hopefully, I find that answer in the 81 answers to that question. Thank you again. – ExecChef Apr 30 '19 at 19:56

1 Answers1

2

It seems that some entries of suppliers doesn't have an InvType. That property is sometimes null, therefore you receive a NullReferenceException because you are calling Contains() method on a null value property.

The problem doesn't occur in your first example, because you were using Linq to Entities. In the second example you are calling ToList() after the first query. After that, everything will continue to work in memory (Linq to Objects). Then you have to check for null in any where condition:

var supplies2 = supplies.Where(s => s.InvType != null && s.InvType.Contains(YourRadioButton ?? string.Empty));

I think it is better to remove ToList() from the first query. Add your where conditions to it and let the PagedList execute the query for you:

public ActionResult Index(string searchString, string SType, int? page, string YourRadioButton)
{
     var supplies = db.ICS_Supplies.AsQueryable();

     if (!String.IsNullOrWhiteSpace(YourRadioButton))
     {
         supplies = supplies.Where(s => s.InvType.Contains(YourRadioButton));
     }

     if (!String.IsNullOrWhiteSpace(searchString))
     {
         supplies = supplies.Where(s =>  s.ItemDescription.Contains(searchString));
     }

     supplies = supplies.OrderBy(g => g.ItemDescription)

     // Add paging to the search results
     var pageNumber = page ?? 1;
     return View(supplies.ToPagedList(pageNumber, 10));
}
Marc
  • 3,905
  • 4
  • 21
  • 37
  • Thank you very much for breaking this down so that I understand it. I was not making the connection, in my head, with ToList(). This now works as expected. The only thing is that it does not bring anything back if the searchString and/or YourRadioButtion has no value. Is there a way to bring back ALL results (ie ignore the filter on that option) if the string has no value? – ExecChef Apr 30 '19 at 20:14
  • I have updated the answer. This should ignore empty filters and bring back all the results. – Marc Apr 30 '19 at 20:18
  • When, I updated my code, I got all new errors: Cannot implicitly convert type 'System.Linq.Iqueryable >ICS20Web.Models.ICS_Supplies> to 'System.Data.Entity.DbSet……… – ExecChef Apr 30 '19 at 20:29
  • Ah yes... I forgot to add `.AsQueryable()`. I hope it is compiling at your end now :) Right now I don't have a Visual Studio here to test it. – Marc Apr 30 '19 at 20:37
  • It's compiling now, and works exactly as I wanted it to work! Thank you for all of your help and for fully explaining why things were not working, as I had them originally. This has been a 3 day headache. Thank you. – ExecChef Apr 30 '19 at 20:42
  • You're welcome! 3 day headache sounds not good :) I'm happy to hear that it helped you and you have learned a little bit from my answer. – Marc Apr 30 '19 at 20:53