Search code examples
c#entity-framework-coreasp.net-core-mvc

How to make dropdown using selected list in ASP.NET Core MVC


I have two tables Product and Category and linked them then I have filled in data.

I want to select the name of the category for add new item and this name is found in the database When I select the name of category from form I can't get the id this name and storage it in the Product table select category name select category name

When I press on the save show this error massage:

error when press save error when press save

In the show product can't show the name of the category:

enter image description here enter image description here

I have these tables

using System.ComponentModel;

namespace Project.Models.ProjectClasses
{
    public class Product
    {
        public int ProducId { get; set; }
        public string? Name { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
        public int? IDCategory { get; set; }

        public virtual Category? category { get; set; }
        public DateTime? Added_Date { get; set; }=DateTime.Now;
    }

    public class Category
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public virtual ICollection<Product> ?product { get; set; }
    }
}

This is the ProductController:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Project.ECommerceDbContext;
using Project.Migrations;
using Project.Models.ProjectClasses;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http.Headers;

namespace Project.Controllers
{
    public class ProductsController : Controller
    {
        private readonly ECommerce _CONTEXT;

        public ProductsController(ECommerce CONTEXT)
        {
            _CONTEXT = CONTEXT;
        }

        public IActionResult product()
        {
            IEnumerable<Product> Viewproduct = _CONTEXT.Products.ToList();
            return View(Viewproduct);
        }

        public void Selectecategorywithproduct(int selected = 0)
        {
            List<Category> category = _CONTEXT.Categories.ToList();
            SelectList listItems = new SelectList(category, "Id", "Name", selected);
            ViewBag.SelectedList = listItems;
        }

        public IActionResult Add_Item()
        {
            Selectecategorywithproduct();
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Add_Item(Product Newproduct)
        {
            if (ModelState.IsValid)
            {
                var category = _CONTEXT.Categories.Find(Newproduct.IDCategory);

                Newproduct.IDCategory = category?.Id;
                 if (category?.Id != null) // تحقق من وجود الفئة المحددة
                {
                    Console.WriteLine("error");
                    _CONTEXT.Products.Add(Newproduct);
                    _CONTEXT.SaveChanges();
                    TempData["AddNewProduct"] = $"The product {Newproduct.Name} has been added successfully";
                    return RedirectToAction(nameof(product));
                }
                else
                {
                    ModelState.AddModelError("IDCategory", "Please select a valid category");
                    Selectecategorywithproduct();
                }
                //}
            }

            return View(Newproduct);
        }
    }
}

Here is the Product.cshtml view:

@using Project.Models.ProjectClasses;

@model IEnumerable<Product>
@{
    ViewData["Title"] = "product";
}

<h1>product</h1>
<div>
    @if (TempData["AddNewProduct"] != null)
    {
        <div id="addProductMessage" class="alert alert-@TempData["AddNewProduct"]" role="alert" style="color:aquamarine">
            @TempData["AddNewProduct"]
        </div>
        <script>
            setTimeout(function () {
                $("#addProductMessage").fadeOut("slow", function () {
                    $(this).remove();
                });
            }, 3000);
        </script>
    }

    @if (TempData["EditProduct"] != null)
    {
        <div id="editProductMessage" class="alert alert-@TempData["EditProduct"]" role="alert" style="color:aquamarine">
            @TempData["EditProduct"]
        </div>
        <script>
            setTimeout(function () {
                $("#editProductMessage").fadeOut("slow", function () {
                    $(this).remove();
                });
            }, 3000);
        </script>
    }

    @if (TempData["DeleteProduct"] != null)
    {
        <div id="deleteProductMessage" class="alert alert-@TempData["DeleteProduct"]" role="alert" style="color:red">
            @TempData["DeleteProduct"]
        </div>
        <script>
            setTimeout(function () {
                $("#deleteProductMessage").fadeOut("slow", function () {
                    $(this).remove();
                });
            }, 3000);
        </script>
    }

    <div class="text-end">
        <a asp-controller="Products" asp-action="Add_Item" class="btn btn-success">Add new item</a>
    </div>
    <table class="table table-hover">
    <thead >
            <tr class="table-primary">
                <th scope="row"></th>
            <th>Product Name</th>
            <th>Product Categroy</th>
            <th>Price</th>
            <th>Quantity</th>
            <th>Added Date</th>
            <th></th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var product in Model)
        {
                <tr class="table-light">
                <td>@product.ProducId</td>
                <td>@product.Name</td>
                    <td>
                        @if (product.IDCategory == null||product.IDCategory==0)
                        {
                            <span>Not select</span>
                        }                        
                        else
                        {
                           @product.category!.Name
                        }
                    </td>

                <td>$ @product.Price</td>
                <td>@product.Quantity</td>
                <td>@product.Added_Date</td>
                    <td>

                        <a asp-controller="Products" asp-action="Edit_Item" asp-route-id="@product.ProducId" class="btn btn-success"><i class="bi bi-pencil"></i> Edit</a>
                        <a asp-controller="Products" asp-action="Delete_Item" asp-route-id="@product.ProducId"  class="btn btn-danger"><i class="bi bi-trash3"></i> Delete</a>
                    </td>
                <td></td>
            </tr>
        }
    </tbody>
</table>

</div>

And here is the Add_item.cshtml view:

@using Project.Models.ProjectClasses;
@model Product
@{
    ViewData["Title"] = "Add Item";
}

<h1>Add Item</h1>

<form method="post">
    <fieldset>          
        <div class="form-group">
            <label asp-for="Name" class="form-label mt-4">Product Name</label>
            <input class="form-control" asp-for="Name" placeholder="Enter Product Name">
            <span asp-validation-for="Name" class="text-danger"></span>
        </div>
        <div class="form-group">
            <label asp-for="Price" class="form-label mt-4">Price</label>
            <input class="form-control" asp-for="Price" placeholder="Price">
            <span asp-validation-for="Price" class="text-danger"></span>
        </div>  
         <div class="form-group">
            <label asp-for="Quantity" class="form-label mt-4">Quantity</label>
            <input class="form-control" asp-for="Quantity" placeholder="Quantity">
            <span asp-validation-for="Quantity" class="text-danger"></span>
        </div>  
       <div class="form-group">
           <label asp-for="IDCategory" class="form-label mt-4">Category ID</label>
            <select class="form-control" asp-items="ViewBag.SelectedList">
                <option value="0">Selecte Category</option>

           </select>
            <input type="hidden" id="IDCategoryHidden" name="IDCategoryHidden" value="" />

            <span asp-validation-for="IDCategory" class="text-danger"></span>
       </div>
        <p></p>
        <button type="submit" class="btn btn-primary"><i class="bi bi-check2-all"></i> Save</button>
        <a asp-controller="Products" asp-action="product" class="btn "><i class="bi bi-backspace"></i> Go Back</a>
    </fieldset>
   
</form>
@section Scripts
    {
    <partial name="_ValidationScriptsPartial" />
    
}

Please I want to solve this problem


Solution

  • Use the below code, the issue could be fixed. The root cause for the issue is you are not using select tag correctly. We should have asp-for= inside <select class="form-control" asp-for="IDCategory" asp-items="ViewBag.SelectedList">.

    And we also should use <input type="hidden" asp-for="IDCategory" value="" /> to receive the selected value.

        <div class="form-group">
            <label asp-for="IDCategory" class="form-label mt-4">Category ID</label>
            <select class="form-control" asp-for="IDCategory" asp-items="ViewBag.SelectedList">
                <option value="0">Selecte Category</option>
    
            </select>
            @* <input type="hidden" id="IDCategoryHidden" name="IDCategoryHidden" value="" /> *@
            <input type="hidden" asp-for="IDCategory" value="" />
    
            <span asp-validation-for="IDCategory" class="text-danger"></span>
        </div>
    

    Test Result

    enter image description here