不确定如何解决我的 System.NullReferenceException

Not Sure How To Resolve My System.NullReferenceException

我在 MVC5 中有一个索引(列表)视图,它是从模型 (Table ICS_Supplies) 填充的。

我在字段 ItemDescription (varchar) 上添加了一个文本框来为用户添加搜索过滤器。这工作得很好,如下所示:

查看

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

控制器

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));
}

这非常有效。如果 searchString 为 null,它会返回所有结果。如果 searchSring 有值,它会返回 ItemDescription 包含 searchString 值的任何结果。

我正在尝试向索引视图添加一个单选按钮,以便用户还可以筛选字段 InvType,这是一个 char(1) 字段。它可以是 F(表格)或 S(供应品)。因此,我根据所选内容将 YourRadioButton 的值设置为 F 或 S。 . .如下(带新代码)

索引

<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>

然后我用额外的代码更新了 Controller,如下所示:

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));
}

现在,我收到以下错误

System.NullReferenceException

它指的是以下代码行(我添加的)

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

我的问题是 。 . .为什么这会引发 NullReferenceException,而另一行如果为 null 则工作正常?我该如何解决这个问题 - 或者是否有更好的方法将第二个过滤器添加到我的代码中?

无论是否为空,此行都可以正常工作。除了使用 YourRadioButton 的值而不是 searchString 之外,它们的编写方式完全相同,而且我使用的是 InvType 字段而不是 ItemDescription。

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

请记住,我对 MVC5 和 C# 都非常陌生,因此解释原因对我的进步有很大帮助。

似乎没有很多关于在 MVC5 中使用单选按钮的信息。 . .旧 Asp.net 形式中的一个相当简单的概念。

suppliers 的某些条目似乎没有 InvType。 属性 有时为 null,因此您会收到 NullReferenceException,因为您在空值 属性.

上调用 Contains() 方法

您的第一个示例中没有出现该问题,因为您使用的是 Linq to Entities。 在第二个示例中,您在第一个查询之后调用 ToList()。之后,一切都将继续在内存中工作(Linq to Objects)。然后你必须在任何 where 条件下检查 null:

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

我认为最好从第一个查询中删除 ToList()。向其中添加您的 where 条件,让 PagedList 为您执行查询:

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));
}