I am trying to create a view model that allows the user to create a new product by typing in the products new name and then select which parent category it belongs to, which then filters the sub category and the user selects the appropriate sub-category. I am currently just trying to have both a drop down list of all parent categories and a drop down list of all subcategories, but I am getting a null refernce for the parent category in the view.
Models
public class Product
{
[Key]
public int ProductID { get; set; }
[Required]
[Display(Name = "Item Name")]
public string ProductName { get; set; }
public int ProductSubcategoryID { get; set; }
[Required]
public ProductSubcategory ProductSubcategory { get; set; }
}
public class ProductSubcategory
{
[Key]
public int ProductSubcategoryID { get; set; }
[Required]
public int ParentCategoryID { get; set; }
public ParentCategory ParentCategory { get; set; }
[Required]
[Display(Name = "Type")]
public string ProductSubcategoryDescription { get; set; }
}
public class ParentCategory
{
[Key]
public int ParentCategoryID { get; set; }
[Required]
public string ParentCategoryDescription { get; set; }
public IEnumerable<ProductSubcategory> ProductSubcategories { get; set; }
}
View Model
public class CreateProductViewModel
{
public IEnumerable<ParentCategory> ParentCategories{ get; set; }
public IEnumerable<ProductSubcategory> ProductSubcategories { get; set; }
public Product Product { get; set; }
}
Controllers
// GET: Products/Create
public IActionResult Create()
{
var parentCategories = _context.ParentCategories.ToList();
var productSubcategories = _context.ProductSubcategories.ToList();
var viewModel = new CreateProductViewModel
{
ParentCategories = parentCategories,
ProductSubcategories = productSubcategories
};
return View(viewModel);
}
// POST: Products/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ProductID,ProductName,VendorID,ProductSubcategoryID,ParentCategoryID,LocationID,QuantityPerUnit,UnitsInStock,UnitsInOrder,ReorderLevel,ProductComment,ProductMedia")]Product product)
{
_context.Add(product);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
view
@model PrototypeWithAuth.ViewModels.CreateProductViewModel
@{
ViewData["Title"] = "Create";
Layout = "~/Views/Shared/View.cshtml";
}
<h1>Create</h1>
<h4>Product</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">
<label asp-for="Product.ProductName" class="control-label"></label>
<input asp-for="Product.ProductName" class="form-control" />
<span asp-validation-for="Product.ProductName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.ProductSubcategoryID" class="control-label"></label>
<!--<input asp-for="Product.ProductSubcategoryID" class="form-control" />-->
@Html.DropDownListFor(s => s.Product.ProductSubcategoryID,
new SelectList(Model.ProductSubcategories, "ProductSubcategoryID", "ProductSubcategoryDescription"),
"Select Subcategory", new { @class = "form-control" })
<span asp-validation-for="Product.ProductSubcategoryID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Product.ProductSubcategory.ParentCategoryID" class="control-label"></label>
<!--<input asp-for="ProductSubcategoryID" class="form-control" />-->
@Html.DropDownListFor(c => c.Product.ProductSubcategory.ParentCategoryID,
new SelectList(Model.ParentCategories, "ParentCategoryID", "ProductSubcategoryDescription"),
"Select Category", new { @class = "form-control" })
<span asp-validation-for="Product.ProductSubcategory.ParentCategoryID" class="text-danger"></span>
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
When trying to add a new product I get a null reference for ParentCategory
, but if I do not us a html helper tag for a dropdown than the form works. Thank you in advance