Warm tip: This article is reproduced from stackoverflow.com, please click
asp.net-mvc c#

Partial view crashes on non-existent data

发布于 2020-03-28 23:17:22

I'm trying to get a partial view to display some data. It is nestled in another non-partial view like this:

<div id="ProizvodPodaci" style="display:flex;justify-content:center;align-items:center;">
    @{Html.RenderAction("PrikazStanja", "Proizvod", new { Id = 0});}
</div>

And I'm giving it data like this:

<script type="text/javascript">
function pretrazi(ID) {
    var a = document.getElementById("proizvodID").value;
    if (a == "") {
        ID = 0;
    }

    if (ID == 0) {
        alert("Molimo unesite ID za pretragu.");
        return;
    }

    $.ajax({
        url: '@Url.Action("PrikazStanja", "Proizvod")',
        data: { id: ID},
        success: function (result) {
            $('#ProizvodPodaci').html(result);
        }
    });
}

Here is the partial view itself. Note the "commented out parts" with @* and *@.

@model IEnumerable<azilZaPse.Models.ProizvedeniProizvodiBO>

<table class="table">
    <caption>Rezultati pretrage za proizvod: @* @Model.FirstOrDefault().proizvod.IdProizvoda *@ </caption>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.proizvodjac.IdProizvodjaca)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.proizvodjac.NazivProizvodjaca)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.proizvodnja.DostupneKolicine)
        </th>
    </tr>

    @foreach (var item in Model)
    {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.proizvodjac.IdProizvodjaca)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.proizvodjac.NazivProizvodjaca)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.proizvodnja.DostupneKolicine)
        </td>
    </tr>
    }

    <tr>
        <td colspan="3">
            Trenutne količine u azilu su: @* @Model.FirstOrDefault().proizvod.Kolicina *@
        </td>
    </tr>
</table>

I'm basically providing it with an IEnumerable list of a class (ProizvedeniProizvodiBO) that consists of 3 other classes (Proizvodjac, Proizvodnja and Proizvod). The classes are "filled" through linq.

If I provide it with a "valid" set of data (aka some that actually exists in the database) all works as it should. If I provide it with non-valid data (like an ID that does not exist in the database) the two commented lines crash the entire thing. With them removed, all is as it should, the other lines work ok when given "invalid input" and just don't display anything (as they should).

You may notice that I'm trying to give it "first or default". I also tried "take(1)". Both proizvod.IdProizvoda and proizvod.Kolicina and generally the entire proizvod should be the exact same in all the rows (only the other 2 classes are different per row), but I only need it displayed once.

Basically is there a way to put in some default values for the 2 lines? Sorry if the question's a mess.

Questioner
Drvo Foka
Viewed
82
daremachine 2020-01-31 17:58

You need use null conditional operator (?.) is colloquially referred to as the "Elvis operator".

@Model.FirstOrDefault()?.proizvod?.IdProizvoda 

From microsoft doc

Available in C# 6 or later, a null operator uses an access, or., [] Element to access a C # member to perform an operation on its operand only if the operand is evaluated as other than null; otherwise, it returns null. It is If a evaluates to null, the result of a? .X or a? [X] is null. If a is evaluated to be non-zero, the result of a? .X or a? [X] is the same as the result of a.x or a [x], respectively.

And for default value you can use razor @(_your_code_here).

For

  1. default value you can use colasence operator ??

@(Model.FirstOrDefault()?.proizvod?.IdProizvoda ?? "my default value")

  1. different values ternary operator ? :

@(Model.FirstOrDefault()?.proizvod?.IdProizvoda ? "yes" : "no")

Hope it help