I have two classes "Customer" and "Deals" the customer has a foreign key relationship to the deal. The user should choose from the dropdown list the customer that makes the deal. So I create a ViewModel class that contains a SelectListItem of customers and a deal and update the creat in the deal controller, the error appears when creating the deals:
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object.
-ViewModel:
public class CreateDealVM
{
public Deals deal { get; set; }
public IEnumerable<SelectListItem> selectedCustomer { get; set; }
public int selectedCustomerId { get; set; }
}
}
The DealController methods
public IActionResult Create()
{
Deals deal = new Deals();
List<Customer> customerList = _context.Customers.ToList();
CreateDealVM vm = new CreateDealVM();
vm.selectedCustomer = new SelectList(customerList, "customerId", "customerName");
vm.deal = deal;
return View(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateDealVM vm)
{
if (ModelState.IsValid)
{
try
{
vm.deal.customer =_context.Customers.Find(vm.selectedCustomerId);
_context.Deals.Add(vm.deal);
_context.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return View(vm);
}
return View();
}
Deal Model class:
namespace MyShop.Models
{
[Table("Deals")]
public class Deals
{
[Key]
[Display(Name = "ID")]
public int dealId { get; set; }
[ForeignKey("Customer")]
[Display(Name = "Customer")]
public Customer customer { get; set; }
[Display(Name = "CustomerName")]
public string? parentCustomerName { get; set; }
[Display(Name = "product")]
public DealTypeEnum product { get; set; }
[Display(Name = "Date")]
public DateTime saleDate { get; set; }
[Display(Name = "Quantity")]
public float quantity { get; set; }
[Display(Name = "Price")]
public float price { get; set; }
}
The view.cshtml page :
@model MyShop.ViewModels.CreateDealVM
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Deals</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
@Html.LabelFor(model => model.selectedCustomer, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.selectedCustomerId, Model.selectedCustomer,"--Select--" )
</div>
</div>
<div class="form-group">
<label asp-for="deal.product" class="control-label"></label>
<select asp-for="deal.product" class="form-control"></select>
<span asp-validation-for="deal.product" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="deal.saleDate" class="control-label"></label>
<input asp-for="deal.saleDate" class="form-control" />
<span asp-validation-for="deal.saleDate" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="deal.quantity" class="control-label"></label>
<input asp-for="deal.quantity" class="form-control" />
<span asp-validation-for="deal.quantity" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="deal.price" class="control-label"></label>
<input asp-for="deal.price" class="form-control" />
<span asp-validation-for="deal.price" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
I tried this link ASP.NET MVC DropdownlistFor Object reference not set to an instance of an object? but it did not work.
I suppose you have this problem not when you render the Create.cshtml
view the first time, but after you press Create button and the ModelState.IsValid
in the public ActionResult Create(CreateDealVM vm)
is false
.
After that you just render the Create.cshtml
view by calling
return View();
This is why the Model
is null
when you trying to render the Create.cshtml
view the second time.
You should use debugger to check this and if this is exactly what's happening replace return View();
line by
return View(vm);
In additional analyze your code in the view, to find out why the data model become not valid when passed from view to controller.