Search code examples
entity-frameworkasp.net-coremodel-view-controllerlinq-to-entitiesrepository-pattern

Returning object details in the View based on the object ID ASP.net core MVC


I'm building online catalog for phones, I have two controller one for phone Catalog and second for phone's details.With catalog everything is fine, now my goal is to see phone details after clicking on the phone's name or photo in the catalog.I think that with phone's id, its easier to solve this task, also I use repository pattern.

This Catalog' s Controller:

public class PhonesCatalog : Controller
    {
        private readonly IPhoneRepository _repository;
        public int PageSize = 6;

        public PhonesCatalog(IPhoneRepository repository)
        {
            _repository = repository;
        }

       
        [HttpGet]
        public IActionResult Catalog(int productPage = 1)
            => View(new ProductsListViewModel 
            { 
                Phones = _repository.Phones
                    .OrderBy(x => x.PhoneId)
                    .Skip((productPage -1) * PageSize)
                    .Take(PageSize),
                PagingInfo = new PagingInfo
                {
                    CurrentPage = productPage,
                    ItemsPrePage = PageSize,
                    TotalItems = _repository.Phones.Count()
                }
            });
    }

The repository pattern:

public interface IPhoneRepository
    {
        IQueryable<Phone> Phones { get; }
        Phone GetPhoneById(int id);
    }
public class EfMobileStoreRepository : IPhoneRepository
    {
        private readonly MobileStoreCatalogContext _context;

        public EfMobileStoreRepository(MobileStoreCatalogContext context)
        {
            _context = context;
        }

        public IQueryable<Phone> Phones => _context.Phones;

        public Phone GetPhoneById(int id) => _context.Phones
                                                    .FirstOrDefault(p => p.PhoneId == id);

    }

and here is Phone detail controller and view:

public class PhonesDetails : Controller
    {
        private readonly IPhoneRepository _repository;

        public PhonesDetails(IPhoneRepository repository)
        {
            _repository = repository;
        }

        [HttpGet]
        public IActionResult Details(int id)
        {
            
            return View(_repository.GetPhoneById(id));
        }
    }
@model Mobile_Store_Catalog_wandio.Models.Phone
    <h4>Phone Details</h4>
<div class="row">
            <p>@Model.PhoneName</p>
            <p>@Model.Manufactor</p>
            <p>@Model.OperationSystem</p>
            <p>@Model.Processor</p>
            <p>@Model.Memory</p>
            <p>@Model.ScreenResolution</p>
            <p>@Model.Size</p>
            <p>@Model.Wight</p>
</div>

Here Catalog View:

@model ProductsListViewModel
<h1>Phone Catalog</h1>
<div class="container-fluid">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-3 btn-group-vertical text-center">
                Filter
                Search
            </div>
            <div class=" row col-md-9">
                @foreach (var p in Model.Phones)
                {
                    <div class=" col-md-4 border border-dark">
                        <a href="@Url.Action("Details", "PhonesDetails")">
                            <img class="img-fluid" src="/Images/@p.ImageName"/>
                        </a>
                        <p class="text-center container">@p.PhoneName</p>
                        <p class="text-white text-center bg-success">@p.Price.ToString("C2")</p>
                    </div>
                }
            </div>
        </div>
    </div>
</div>
<div class="row">
    <div page-model="@Model.PagingInfo" page-action="Catalog" page-classes-enabled="true"
         page-class="btn" page-class-normal="btn-outline-dark"
         page-class-selected="btn-primary" class="btn-group-toggle m-1 al">
    </div>
</div>

and here is the ProductViewList code:

public class ProductsListViewModel
    {
        public IEnumerable<Phone> Phones { get; set; }
        public PagingInfo PagingInfo { get; set; }
    }

Problem is that when I'm clicking on the phone image,but it takes only first id of phone and returns its detail,it doesn't matter which image is clicked, but I need to return details by id, not only first id Phone detail.

What I'm doing wrong here, can anyone help me?


Solution

  • You can change your code like this:

    <a asp-controller="PhonesDetails" asp-action="Details" asp-route-id="@p.Id"> 
    
    <img class="img-fluid" src="/Images/@p.ImageName"/></a>