-2

Say I have a view like this:

@model Models.CustomerModel

@{
    ViewBag.Title = "Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Details</h2>

<div>
    @*<h4>ApplicationModel</h4>*@
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.FirstName)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.FirstName)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Surname)
        </dt>

        <dd>
            @Html.DisplayFor(model => model.Surname)
        </dd>
       </dl>
</div>

Say CustomerModel also has a collection of Orders. The Order class looks like this:

public class Order {
public int OrderID {get; set; }
public datetime OrderDate {get; set; }

How can I put all the Orders liked to the Customer on the same view? I have tried this (under the code above):

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.OrderID)
        </th>
    <th>
            @Html.DisplayNameFor(model => model.OrderDate)
        </th>
    </tr>

@foreach (var item in model.Orders)
{
    <tr>
        <td>
            @Html.DisplayFor(item => item.OrderID)
        </td>
    <td>
            @Html.DisplayFor(item => item.Description)
        </td>
    </tr>
}

The error I get is:

The parameters dictionary contains a null entry for parameter 'orderid' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Delete(Int32)'.

If I remove the second fragment of code (for each loop), then it works properly. How do I add the second fragment of code?

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
w0051977
  • 15,099
  • 32
  • 152
  • 329

2 Answers2

0

Try add null check

@if(Model.Orders != null)
{
  foreach (var item in Model.Orders)
  {
      <tr>
          <td>
              @Html.DisplayFor(t => item.OrderID)
          </td>
      <td>
              @Html.DisplayFor(t => item.Description)
          </td>
      </tr>
  }
}

or using LINQ you can

if(Model.Orders.Any())

if it doesn't help then see this question

Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
  • The error I get with this is: "CS0103: The name 'model' does not exist in the current context" – w0051977 Aug 01 '17 at 09:25
  • 1
    Because it has to be `Model` – jAC Aug 01 '17 at 09:25
  • Ohh, yes. Use "Model" not "model" – Roman Marusyk Aug 01 '17 at 09:25
  • It now says: "A local or parameter named 'item' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter" – w0051977 Aug 01 '17 at 09:30
  • 1
    `@Html.DisplayFor(m => item.Description)`. You cannot declare a new `item` in your lambda, if it's already used. – jAC Aug 01 '17 at 09:32
  • @w0051977 You did change it on both `DisplayFor`, didn't you? – jAC Aug 01 '17 at 09:35
  • @jAC, I rebuilt the project and it is working now. Thanks. What is m in the lambda expression? It is passed as an input parameter but is not used. – w0051977 Aug 01 '17 at 09:38
  • 1
    @w0051977 The part of the lambda before `=>` (here `t` or `m`) declares a variable, that references the `Model`, since `DisplayFor` usually directly should reference some `Model.Property` (e.g. `Html.DisplayFor(m => m.FirstName)`. This is a workaround to make `DisplayFor` work in a loop. If you're uncomfortable with it, simply use `Html.Display(item.Property)`. See: https://stackoverflow.com/questions/3419711/how-can-i-use-html-displayfor-inside-of-an-iterator – jAC Aug 01 '17 at 09:42
0

You can make OrderId Nullable in CustomerModel

public int? OrderID {get; set; }

OR check the Null value coming from Database for OrderId (If OrderId is not supposed to be Null then it's bad data and should be restricted from database itself)

Faisal.lh
  • 29
  • 5