Partial View Primary ASP.NET Controller

I am creating a partial sidebar view that will show the most popular posts on my site. How to create a separate controller to load the model required by the partial view? ( IEnumerable<Post>with popular posts)

Currently, I have created a controller class that loads popular messages, but I keep getting errors when rendering partial, since I cannot call the controller and load the partial model. For example, if I call it from a view where I create one post, the model types will not match ( Postvs IEnumerable<Post>)

This is mine SidebarController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using GoBaron.Front.Models;

namespace GoBaron.Front.Controllers
{
    public class SidebarController : Controller
    {
        private readonly ApplicationDbContext _context;

        public SidebarController(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<IActionResult> PopularPosts()
        {
            return PartialView(await _context.Posts
                .Where(p => p.IsActive == true)
                .OrderByDescending(p => p.Id)
                .Take(5)
                .ToListAsync());
        }
    }
}

And this is my partial view PopularPosts.cshtml:

@model IEnumerable<GoBaron.Front.Models.Post>
@using GoBaron.Front.Data.Extensions

@if (Model.Any())
{
    <div class="sidebar-item" id="topTrending">
        <header class="sidebar-item__header">
            <h1>Najpopularniejsze</h1>
        </header>
        <div class="sidebar-item__content">
            @foreach (var item in Model)
            {
                <a asp-controller="Post" asp-action="Details" asp-route-id="@item.Id" asp-route-slug="@item.Title.ConvertToSlug()" title="@item.Title">
                    <div class="sidebar-post-item" style="background-image:url('@item.PosterUrl')">
                        <span class="sidebar-post-item__counter">+5</span>
                        <span class="sidebar-post-item__title">@item.Title</span>
                    </div>
                </a>
            }
        </div>
    </div>
}

, , , :

@await Html.PartialAsync("~/Views/Sidebar/PopularPosts.cshtml")
+4
1

. , , db.

ViewComponent. , InvokeAsync . InvokeAsync , db :

public class PopularPostsViewComponent: ViewComponent
{
    private readonly ApplicationDbContext _context;

    public PopularPostsViewComponent(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        var posts = await _context.Posts
            .Where(p => p.IsActive == true)
            .OrderByDescending(p => p.Id)
            .Take(5)
            .ToListAsync();

        return View(posts);
    }
}

. Default.cshtml ( return View() ), Views/Shared/Components/PopularPosts/Default.cshtml. , :

@model IEnumerable<GoBaron.Front.Models.Post>
@using GoBaron.Front.Data.Extensions

@if (Model.Any())
{
    <div class="sidebar-item" id="topTrending">
        <header class="sidebar-item__header">
            <h1>Najpopularniejsze</h1>
        </header>
        <div class="sidebar-item__content">
            @foreach (var item in Model)
            {
                <a asp-controller="Post" asp-action="Details" asp-route-id="@item.Id" asp-route-slug="@item.Title.ConvertToSlug()" title="@item.Title">
                    <div class="sidebar-post-item" style="background-image:url('@item.PosterUrl')">
                        <span class="sidebar-post-item__counter">+5</span>
                        <span class="sidebar-post-item__title">@item.Title</span>
                    </div>
                </a>
            }
        </div>
    </div>
}

, , InvokeAsync. , :

@await Component.InvokeAsync("PopularPosts")

, .Net Core 1.1 , :

<vc:popular-posts></vc:popular-posts>

PS. , , .

+8

Source: https://habr.com/ru/post/1672508/


All Articles