【问题标题】:ASP.NET Core MVC - Partial view only renders on one pageASP.NET Core MVC - 部分视图只呈现在一页上
【发布时间】:2018-11-22 20:53:55
【问题描述】:

我有一个 ViewBag.count 的部分视图,它在 ShoppingCartController 中定义。问题是 ViewBag 只会在您位于 ShoppingCart 视图时显示。我希望在所有视图上都能看到 ViewBag。我该如何解决?我目前正在渲染这样的部分:

@Html.Partial("_ShoppingCart", new List<bytme.Models.ShoppingCartModel>())

名为 _ShoppingCart 的局部视图:

<span class="badge">@ViewBag.count</span>

【问题讨论】:

  • 您的部分没有@model xxx,因此将new List&lt;bytme.Models.ShoppingCartModel&gt;() 传递给它没有意义。部分不应该有&lt;html&gt;&lt;body&gt; 标签。如果您调用的控制器方法为ViewBag.count 设置了一个值,那么该值将显示在您的部分中。

标签: c# html asp.net-mvc razor asp.net-core-mvc


【解决方案1】:

您应该创建一个单独的操作方法,该方法返回呈现页面的购物车部分所需的 HTML 标记,并使用 Html.Action 方法将其包含在您的所有视图中。

你也可以用ChildActionOnly属性装饰这个action方法,这样用户就不能通过请求url/ShoppingCart/Cart直接访问这个action方法。

[ChildActionOnly]
public ActionResult Cart()
{
    ViewBag.ItemCount = 2;  // replace hard coded value with your actual value
    return PartialView();
}

在您的局部视图 (~/Views/Shared/Cart.cshtml) 中,您可以编写页面购物车段所需的 HTML 代码。

<span class="mycart">
    Total items in cart @ViewBag.ItemCount
</span>

这里我们使用 ViewBag 将项目计数数值从 action 方法传递到它的局部视图。但是您可以使用视图模型并使用强类型视图方法将数据从您的操作方法传递到部分视图(这是我的首选方法)。

现在在您想要呈现购物车 HTML 的其他视图/布局文件中,您可以调用 Html.Action 方法

<div>
   @Html.Action("Cart","ShoppingCart")
</div>
<h1>Welcome to my site</h1>

当 razor 执行你的视图时,它会看到这个 Html.Action 方法和那个将被执行并且那个输出(由 action 方法生成的 HTML 标记),将包含在为当前视图生成的最终输出中.

我正在使用PartialView 方法,这样它就不会尝试执行布局代码。 (人们犯了这个错误并获得了对 Cart 操作方法的无限调用。

对于 Asp.Net Core 项目

如果你想在 asp.net core 项目中做同样的事情,你可以使用 View 组件来达到同样的效果。

创建一个视图组件来呈现购物车。

public class CartViewComponent : ViewComponent
{        
    public IViewComponentResult Invoke(string name)
    {
        var totalItemCount = 3;
        return View(totalItemCount);
    }
}

~/Views/Shared/Components/Cart 目录中为该视图组件创建一个名为Default.cshtml 的剃刀视图,您可以在其中包含剃刀代码/HTML 标记以呈现所需的HTML。在此示例中,我使用了强类型方法,其中我的视图被严格输入为 int 类型,并且在调用 View 方法时,我从 Invoke 方法传递了一个 int 值。

@model int
<span>
    Total items : @Model
</span>

现在您可以通过调用Component.InvokeAsync 方法在其他视图/布局文件中调用此视图组件。

<div>
   @await Component.InvokeAsync("Cart")
</div>
<h1>Welcome to my site</h1>

【讨论】:

  • 我试过这个,但@Html.Action 不存在。只有@Html.ActionLink 是一个选项
  • 你在使用 asp.net core 吗?
  • 是的,我将.csproj 添加到了PackageReferences for asp.net core 的问题中
  • 我发布了处理 asp.net 核心用例的答案的更新。
  • 成功了!非常感谢,虽然我不需要在我的剃刀视图中调用模型。不能感谢你! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 2019-06-01
相关资源
最近更新 更多