如何在Asp.net核心中的ViewComponent之间共享ViewData

Moh*_*ari 7 c# viewdata asp.net-core asp.net-core-viewcomponent

我有两个ViewComponent,我希望使用ViewData或其他技术来共享一些数据,然后在主视图中使用这些数据,但这不是方法,并且当ViewComponent的富到if条件时,每个ViewComponent的ViewData为null.

public class OneViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(Page page, Zone zone)
    {
        //some operation

        string text = "one";

        if(ViewData["data"] != null)
        {
            ViewData["data"] = ViewData["data"].ToString() + text;
        }
        else
        {
            ViewData["data"] = text;
        }

        return View();
    }
}

public class TwoViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(Page page, Zone zone)
    {
        //some operation

        string text = "two";

        if(ViewData["data"] != null)
        {
            ViewData["data"] = ViewData["data"].ToString() + text;
        }
        else
        {
            ViewData["data"] = text;
        }

        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

Cod*_*und 9

ViewData就像ViewBag.仅当您要将数据从Controller传输到View时才使用它.为此,我总是喜欢View Model.

要跨组件传输数据,您有以下两个选项:

使用TempData字典而不是ViewData字典:您需要安装以下包

Install-Package Microsoft.AspNetCore.Mvc.ViewFeatures
Run Code Online (Sandbox Code Playgroud)

在您的Startup课程中,添加此行

services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
Run Code Online (Sandbox Code Playgroud)

你的ConfigureServices方法.我用它CookieTempDataProvider作为impelmentation ITempDataProvider但你可以使用SessionStateTempDataProvider.

要将数据存储到TempData字典中,请使用以下代码:

this.TempData["data"] = "my value";
Run Code Online (Sandbox Code Playgroud)

要从TempData您检索数据,请使用以下代码:

var data = this.TempData["data"];
Run Code Online (Sandbox Code Playgroud)

要在组件视图中使用它:

@this.TempData["data"]
Run Code Online (Sandbox Code Playgroud)

使用HttpContext.Items字典:没有要安装的软件包.在视图组件类中,将数据存储在HttpContext.Items字典中,如下所示:

this.HttpContext.Items["data"] = "my value"; 
Run Code Online (Sandbox Code Playgroud)

并通过执行以下操作访问存储的数据:

var data = this.HttpContext.Items["data"];
Run Code Online (Sandbox Code Playgroud)

在组件视图中,您可以通过执行以下操作获取存储的数据:

@this.Context.Items["data"]
Run Code Online (Sandbox Code Playgroud)

TempData和之间的区别HttpContext.Items:HttpContext.ItemsTempData词典之间的主要区别是:

  • HttpContext.Items 请求结束时清除.
  • 默认情况下TempData,在读取数据时清除.保留显式调用所需的数据TempData.Keep()
  • 您可以在使用时轻松测试视图组件,TempData因为它是一种类型的接口ITempDataDictionary,可以毫无困难地进行模拟.


Tse*_*eng 5

恕我直言,这是一个ViewComponent不适合您的用例的指标。您应该改用部分视图。

局部视图在其父视图操作的上下文中执行,此外您可以将模型传递给局部视图,即产品列表中的产品。

@Html.Partial("PartialName", customViewData)
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,您将提供"one""two"作为部分的模型参数@Html.Partial("PartialName", "one")@Html.Partial("PartialName", "two")

ViewComponents 更像是可重用的逻辑和视图块,其行为类似于控制器 + 操作。但与控制器 + 动作不同的是,ViewComponent可以在多个地方重复使用。

ViewComponents 应该是自给自足的,不依赖于它们之外的数据。

这也进一步表明您正在尝试将与应用程序相关的逻辑从操作移动到视图,并且您的控制器操作中的数据没有为视图使用做好充分准备。

控制器的动作只有 3 个简单的任务:验证用户输入、调用底层应用程序代码(通常称为服务)并准备服务结果供视图使用。话虽如此,更好的解决方案可能是,在您的操作中使用视图模型(而不是ViewData无类型的),准备您需要的所有数据,然后让视图只显示该数据。