简体   繁体   中英

How to null check @Html.DisplayNameFor with IEnumerable - C# & ASP.NET MVC

I'm not sure if I'm searching this incorrectly, but I can't seem to determine as to how to null check @Html.DisplayNameFor .

I have an IEnumerable<model> which has a model.Numbers model.Order and model.Time :

@Html.DisplayNameFor(Model => Model.Numbers)

etc.

I tried doing a this but VS throws an error on:

 @Html.DisplayNameFor(Model => Model?.Numbers) 

But I get this message when I hover over the red squiggly in VS:

An expression tree lambda may not contain a null propagating operator

I've also tried appending where() and @Html.DisplayNameFor(Model => Model.Numbers.Any()) but these do not work.

My code:

@model IEnumerable<BusinessLayer.NumbersModel>

...

<table class="table table-sm">

    <thead class="thead-dark">
        <tr>
            <th>@Html.DisplayNameFor(Model => Model.Numbers)</th>
            <th>@Html.DisplayNameFor(Model => Model.Order)</th>
            <th>@Html.DisplayNameFor(Model => Model.Time)</th>
        </tr>
    </thead>

    @foreach (var item in Model)
    {
        if (item.Numbers != null && item.Order != null && item.Time != null)
        {
            <tr>
                <td>@Html.DisplayFor(m => item.Numbers)</td>
                <td>@Html.DisplayFor(m => item.Order)</td>
                <td>@Html.DisplayFor(m => item.Time)</td>
                <td><i class="m-icon--edit"></i> @Html.ActionLink("Edit", "Edit", new { id = item.ID }, new { @class = "m-numbers__link" })</td>
                <td>
                    @using (Html.BeginForm("Delete", "Numbers", new { id = item.ID }))
                    {
                        <i class="m-icon--delete"></i> <input type="submit" value="Bin" onclick="return confirm('You are about to delete this record');" />
                    }
                </td>
            </tr>
        }
    }
</table>

Model:

public class NumbersModel
{
    public int ID { get; set; }
    public string Numbers { get; set; }
    public string Order { get; set; }
    public string Time { get; set; }
}

Your @model is an IEnumerable<T> . It does not have .Numbers or .Order , the objects it contains do.

DisplayNameFor() only needs to know the type of the expression to get the attribute DisplayAttribute from. The expression you pass to it does not have to calculate to a non-null instance of the object, it will not be executed for its result.

So

<thead class="thead-dark">
    <tr>
        <th>@Html.DisplayNameFor(m => m.First().Numbers)</th>
        <th>@Html.DisplayNameFor(m => m.First().Order)</th>
        <th>@Html.DisplayNameFor(m => m.First().Time)</th>
    </tr>
</thead>

This will work even if .Numbers is null, or .First() is null, or the entire Model is null.

You generally do not need to handle nulls when passing expression trees to the ASP.NET MVC helpers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM