gpt4 book ai didi

c# - 渲染局部 View 时如何调用 Controller Action ?

转载 作者:太空狗 更新时间:2023-10-29 22:10:24 24 4
gpt4 key购买 nike

我正在为侧边栏创建一个局部 View ,它将显示我站点中最受欢迎的帖子。如何创建一个单独的 Controller 来加载局部 View 所需的模型? (IEnumerable<Post>有热门帖)

目前我已经创建了一个 Controller 类来加载热门帖子,但是在渲染部分时我总是遇到错误,因为我无法调用 Controller 并加载部分模型。例如,如果我从呈现单个帖子的 View 中调用它,模型类型将不匹配( PostIEnumerable<Post> )

这是我的 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());
}
}
}

这是我的部分观点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")

最佳答案

这是 View Component 的一个很好的用例而不是局部 View 。您不仅需要呈现 View ,还需要执行从数据库加载热门帖子的逻辑。

创建一个新的 ViewComponent 类而不是 Controller。这包含在其 InvokeAsync 方法中为 View 组件准备模型的逻辑,它可以采用任意数量的参数。在您的情况下,InvokeAsync 不带任何参数,将从数据库加载热门帖子并呈现 View 组件 View :

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);
}
}

现在您需要为该 View 组件创建 View 。默认 View 名称 Default.cshtml(当您执行 return View() 时没有指定 View 名称)并且它应该位于 Views/Shared/Components/PopularPosts/Default.cshtml。这基本上与您当前的局部 View 相同:

@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>
}

然后从任何其他 View ,您将呈现您的 View 组件而不是部分 View 组件,传递 InvokeAsync 所需的任何参数。在您的情况下,您没有参数,因此它将是:

@await Component.InvokeAsync("PopularPosts")

最后,如果您使用的是 .Net Core 1.1 或更高版本,您还可以将其作为标签助手调用:

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

附言。我写了一个article描述您可能会感兴趣的部分、标签助手和 View 组件的用法。

关于c# - 渲染局部 View 时如何调用 Controller Action ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42845883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com