关闭if语句时出现NullReferenceException异常

5

我正在使用 Razor 视图的 MVC。在这个特定的视图中,我传递了类 Bed 的一个实例。 Bed 有一个属性 string Infection。现在,在这个实例中,我有一个布尔值 HasInfection 在视图中定义,我将在其他地方使用它来改变显示内容。最初它声明为

var HasInfection = (Model.Infection.Trim() != "";

并且按预期工作。然而,现在存在这样一种情况,即 Bed 可能为空。以下是第一个代码块:

@{
    ViewBag.Title = "Edit";
    var HasInfection = false;
    if (Model != null)
    {
        HasInfection = Model.Infection.Trim() != "";
    } // I get a NRE on this line whenever Model is null
}

我甚至尝试了复杂的嵌套if-else解决方案,但在if的闭合括号处仍然遇到了NRE错误。

if (Model.Infection == null)
{
    HasInfection = false;
}
else
{
    if (Model.Infection != "")
    {
        HasInfection = true;
    }
    else
    {
        HasInfection = false;
    }
}

我已经尝试了所有的 &/&&/|/|| 的组合,但都没有成功。如果Model为空或者Model.Infection等于"",则HasInfection应该为false。
我做错了什么?
编辑后: 尝试使用var HasInfection = Model != null && !string.IsNullOrWhiteSpace(Model.Infection);(因为Infection可能是“”),仍然出现NullReferenceException错误。即使异常在视图中,问题是否可能存在于控制器中?
public ActionResult EditReservation(int Facility, string Room, string Bed)
{
    var BedModel = New Bed();
    List<Bed> _b = BedModel.GetBed(Facility, Room, Bed);
    Bed result = _b.Where(bed => bed.BedStatus == "R" || bed.BedStatus == "A").FirstOrDefault();
    return View("Edit", result);
}

你在哪一行遇到了空指针异常? - cederlof
@WillDean 我已经尝试了各种组合,只是为了让某些东西能够正常工作。现在的编辑状态是当前的代码。@cederlof 现在我在 var HasInfection = Model != null && !string.IsNullOrWhiteSpace(Model.Infection); 上遇到了异常。在编辑之前,它出现在任何 if 语句的闭合括号上。 - Phillip Copley
1
瞎猜一下...BedModel数据库相关吗?如果它是IQueryable类型,那么当你第一次使用它时,“实际”查询可能会被调用...你尝试在控制器中进行调试,检查_b不为空并且result不为空吗? - Tallmaris
4个回答

5

我也遇到了同样的问题。

当我查看这个问题的第二个评论时,我发现我的异常实际上比NullReferenceException所指向的闭合括号更远35行(在括号外面)。

例如:

    if(Model.Infection != null)
    {
        <p>Some Html</p>
    } //given NullReferenceException location

    <p>Model.Infection</p> //Actual cause of NullReferenceException since 
                           //here Model.Infection can be null

2

您应该能够做到这样:

var HasInfection = Model != null && !String.IsNullOrWhitespace(Model.Infection)

我不认为我曾经将空模型传递给 Razor 视图,但我不明白为什么这样做行不通。

另外,你可以考虑创建一个“NullBed”对象,并将其传递,该对象的行为方式与“missing”床对象的正确行为一致 - 然后您就不需要在所有地方检查 null,因为这可能会变得非常繁琐。

编辑:现在你已经发布了控制器代码,似乎 Model 永远不可能为 null,所以这似乎是一个干扰项。我怀疑你正在错误的地方寻找问题所在。

编辑2:哦,现在它又从控制器代码中消失了。感觉使用调试器的系统化方法可能比 StackOverflow 更有效... 我建议从在控制器中传递一个固定且已知的东西开始,并通过在视图中显示东西来确定发生了什么。

如果您控制 Bed 类,则可以通过向 Bed 添加 HasInfection 属性来帮助自己和您的后继者,在该属性中执行必要的操作以返回布尔值。您还可以通过将 BedStatus 检查移动到属性中来改进控制器。这样做的好处不仅仅是风格上的优化,它还有助于调试此类问题,因为有关床对象的事情将在该代码中发生,而仅剩在视图中的东西(这是调试的可怕地方)会更简单。


请查看我的编辑响应。无论Model是空还是一个新的Bed(其中Bed.Infection为空),我仍然会遇到这个错误,即使使用了你的建议。 - Phillip Copley
1
@Xaruth 呃?你是在利用我的帖子来发泄一下关于“var”关键字的不满吗? - Will Dean
@PhillipCopley - 您的编辑说“var HasInfection = !string.IsNullOrWhiteSpace(Model.Infection);”,这不是我写的,如果Model为空,则一定会失败。您不能在空的Model中执行Model.Infection。 - Will Dean

1
HasInfection = Model != null && !string.IsNullOrWhitespace(Model.Infection);

3
IsNullOrWhiteSpace() 会更好 ;) - Xaruth
1
@Xaruth 呵呵,在我修改之前我没有看到你的评论。干杯 :) - cederlof

0

首先检查 Model 是否为 null,如果 Model 不为 null,则检查 Model.Infection 是否为空。

试试这个:

if(Model != null && Model.Infection != null && Model.Infection.Trim() != "")
{
        HasInfection = true;
}

请不要使用 Trim 和 Equal 验证字符串是否为空!使用面向对象编程! - Xaruth
@Xaruth:感谢您的评论,我已经进行了更改。 - Sudhakar Tillapudi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接