Airizzo
Airizzo

Reputation: 165

I have a Paramater of a non nullable type error in my MVC project

So, I'm making a MVC CRUD app that is connected to my SQL Server. I'm trying to get my Details link to populate the info needed. Instead it is coming up with the error that's in this title. I have tried the C# way to fix it, but it populated without Data. I also tried the old google and search the question here and those suggestions didn't net me much. I'm sure it's a easy fix, I just don't know it. Any help would be appreciated!

This is the Error I'm given.

The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'MVC.Controllers.CustomerController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

Below is my Code, and Proposal_UID is my Key in SQL. Here is my code for my RouteConfig

 public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

Here is my code for my Controller.

public ActionResult Details(int id)
        {
            using (DBModels db = new DBModels())
            {
                return View(db.Proposals.Where(x => x.Proposal_Uid == id).FirstOrDefault());
            }

        }

Here is my Code for my Detail Views

@model MVCSQLCRUDnoTelerik.Models.Proposal

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

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

        <dd>
            @Html.DisplayFor(model => model.Proposal_Uid)
        </dd>
 <dt>
            @Html.DisplayNameFor(model => model.Start_Date)
        </dt>

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

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

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

    </dl>
</div>
<p>
    @Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
    @Html.ActionLink("Back to List", "Index")
</p>

I've tried doing this

public ActionResult Details(int? id)
        {
            using (DBModels db = new DBModels())
            {
                return View(db.Proposals.Where(x => x.Proposal_Uid == id).FirstOrDefault());
            }

        }

It populates the page, but not the information needed inside the boxes.

I've also tried doing this

<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.Proposal_Uid  }) |
    @Html.ActionLink("Back to List", "Index")
</p>

This is the link that shows when I click on the details link and it goes to the error. I omitted the numbers for #

https://localhost:#####/Customer/Details

Now when I type the link into the URL I get the correct info and everything

https://localhost:#####/Customer/Details/1

I know that the problem is in my Views, or Routeconfig file. I just don't know where and no idea how to fix it. Any help would be appreciated.

Here is my Index View

@model IEnumerable<MVCSQLCRUDnoTelerik.Models.Proposal>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Proposal_Uid)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Start_Date)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.End_Date)
        </th>
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Proposal_Uid)
        </td>

        <td>
            @Html.DisplayFor(modelItem => item.Start_Date)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.End_Date)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

Upvotes: 2

Views: 203

Answers (2)

Airizzo
Airizzo

Reputation: 165

In my Index Views code,

@model IEnumerable<MVCSQLCRUDnoTelerik.Models.Proposal>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Proposal_Uid)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Start_Date)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.End_Date)
        </th>
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Proposal_Uid)
        </td>

        <td>
            @Html.DisplayFor(modelItem => item.Start_Date)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.End_Date)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
            @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
        </td>
    </tr>
}

</table>

The action link is actually commented out with the part that we need. It should look like this.

@Html.ActionLink("Details", "Details", new { id=item.Proposal_uid }) |

Your C# code for your action (the code that receives the request) should make sure to have the ? in the parameters section as well, so that if anything can be null, it won't populate a error. It should look like this.

public ActionResult Details(int? id)
{
    using (DBModels db = new DBModels())
    {
        return View(db.Proposals.Where(x => x.Proposal_Uid == id).FirstOrDefault());
    }
}

There may be other things wrong with the code, but this is such a small mistake that when you create the VIEWS code from the Models by right clicking and creating/scaffolding it automatically comments it out. If you have a key in your SQL table, you must uncomment it out or it will keep generating an error until you do.

Upvotes: 1

Tieson T.
Tieson T.

Reputation: 21191

What you have here is correct/valid:

public ActionResult Details(int? id)
{
    using (DBModels db = new DBModels())
    {
        return View(db.Proposals.Where(x => x.Proposal_Uid == id).FirstOrDefault());
    }
}

I would recommend adding a couple of null checks, redirecting to the Index action, just in case:

public ActionResult Details(int? id)
{
    if(id != null)
    {
        using (DBModels db = new DBModels())
        {
            var model = db.Proposals.Where(x => x.Proposal_Uid == id).FirstOrDefault();

            if(model != null)
            {
                return View(model);
            }
        }
    }

    return RedirectToAction("index");
}

Upvotes: 0

Related Questions