简体   繁体   English

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

[英]How share ViewData between ViewComponent in Asp.net core

I have two ViewComponent and i want use ViewData or other technic for share some data between and then use this data in main view, but this is not the way, and ViewData per ViewComponent is null when rich to if condition for both 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();
    }
}

ViewData is just like ViewBag . ViewData就像ViewBag一样。 You use it only if you want to transfer data from Controller to View. 仅当您要将数据从Controller传输到View时才使用它。 For this I always prefer View Model. 为此,我总是喜欢View Model。

For transferring data across component you have the following two options: 要跨组件传输数据,您有以下两个选项:

Using TempData dictionary instead of ViewData dictionary: you need to install the following package 使用TempData字典而不是ViewData字典:您需要安装以下软件包

Install-Package Microsoft.AspNetCore.Mvc.ViewFeatures

In your Startup class, add this line Startup类中,添加此行

services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();

to your ConfigureServices method. 到您的ConfigureServices方法。 I use CookieTempDataProvider as impelmentation of ITempDataProvider but you can use SessionStateTempDataProvider . 我使用CookieTempDataProvider作为ITempDataProvider的ITempDataProvider但您可以使用SessionStateTempDataProvider

To store data into TempData dictionary you use this code: 要将数据存储到TempData字典中,请使用以下代码:

this.TempData["data"] = "my value";

To retrieve data from TempData you use this code: 要从TempData检索数据,请使用以下代码:

var data = this.TempData["data"];

To use it in your component view: 要在组件视图中使用它:

@this.TempData["data"]

Using HttpContext.Items dictionary: there is no package to install. 使用HttpContext.Items字典:没有要安装的软件包。 In your view component class, store your data in HttpContext.Items dictionary like this: 在视图组件类中,将数据存储在HttpContext.Items字典中,如下所示:

this.HttpContext.Items["data"] = "my value"; 

And access to the data stored by doing this: 并通过执行以下操作访问存储的数据:

var data = this.HttpContext.Items["data"];

In your component view, you can get the stored data by doing this: 在组件视图中,您可以通过执行以下操作获取存储的数据:

@this.Context.Items["data"]

The difference between TempData and HttpContext.Items : the main difference between HttpContext.Items and TempData dictionary is: TempDataHttpContext.Items之间的区别: HttpContext.ItemsTempData字典之间的主要区别是:

  • HttpContext.Items is cleared when the request ends. 请求结束时清除HttpContext.Items
  • By default TempData is cleared when the data is read. 默认情况下,在读取数据时会清除TempData To retain the data you need to explicitly call TempData.Keep() 要保留显式调用TempData.Keep()所需的数据
  • You can easily test your view compnent when you use TempData because it is an interface of type ITempDataDictionary which can be mocked without difficulty. 使用TempData时可以轻松测试视图TempData因为它是ITempDataDictionary类型的接口,可以毫不费力地进行ITempDataDictionary

Imho this is an indicator that ViewComponent s are not suitable for your use case. Imho这是一个指示ViewComponent不适合您的用例。 You should use partial views instead. 您应该使用部分视图。

Partial views are executed in the context of their parent'S view action and additionally you can pass a model to the partial, ie a product from a product list. 部分视图在其父视图操作的上下文中执行,此外,您可以将模型传递给部分,即产品列表中的产品。

@Html.Partial("PartialName", customViewData)

In your example above, you'd provide "one" and "two" as the partial's model parameter @Html.Partial("PartialName", "one") , @Html.Partial("PartialName", "two") 在上面的示例中,您将提供"one""two"作为partial的模型参数@Html.Partial("PartialName", "one")@Html.Partial("PartialName", "two")

ViewComponents are more like reusable blocks of logic and view which act similarly to a controler + action. ViewComponents更像是可重用的逻辑和视图块,其作用类似于控制器+动作。 But unlike controller + action, the ViewComponent can be reused in multiple places. 但与控制器+动作不同, ViewComponent可以在多个地方重用。

ViewComponents should be self-sufficient and do not depend on data outside of them. ViewComponents应该是自给自足的,不依赖于它们之外的数据。

This also further more indicates that you are trying to move application related logic from an action to the view and that your data from your controller action isn't sufficiently prepared for the view to consume. 这也进一步表明您正在尝试将与应用程序相关的逻辑从操作移动到视图,并且您的控制器操作中的数据没有充分准备供视图使用。

The controller's action has only 3 simple tasks: Validate user input, call the underlying application code (commonly called services) and prepare the service results for the view to consume it. 控制器的操作只有3个简单的任务:验证用户输入,调用底层应用程序代码(通常称为服务)并为视图准备服务结果以使用它。 That being said, a better solution may be, to use a viewmodel in your action (instead of ViewData which is untyped), prepare all the data you need and then let the view just display that data. 话虽如此,更好的解决方案可能是,在您的操作中使用视图模型(而不是无类型的ViewData ),准备所需的所有数据,然后让视图显示该数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 ModelExpression 绑定到 ASP.NET Core 中的 ViewComponent? - How to bind a ModelExpression to a ViewComponent in ASP.NET Core? 如何在ViewComponent Asp.Net Core中获取当前登录用户 - How get current login user in ViewComponent Asp.Net Core Asp.Net Core 将 ViewComponent 渲染为变量 - Asp.Net Core render ViewComponent to variable ASP.NET Core ViewComponent调用:InvalidCastException - ASP.NET Core ViewComponent Invocation: InvalidCastException 如何在两台服务器之间共享 ASP.NET Core 3 中的会话? - How to share Session in ASP.NET Core 3 between 2 servers? 在 ASP.NET CORE MVC 中使用 CRUD 操作的 ViewComponent - ViewComponent With CRUD Operations in ASP.NET CORE MVC 无法识别 ASP.NET Core ViewComponent 的 Invoke() 方法调用 - ASP.NET Core ViewComponent's Invoke() method call not recognized 使用 Razor Pages 在 Asp.NET Core 2.2 中找不到 ViewComponent - ViewComponent not found in Asp.NET Core 2.2 using Razor Pages ASP.NET Core使用ViewComponent跟踪侧栏的活动页面 - ASP.NET Core track active Page for sidebar using ViewComponent 如何在ASP.NET Core MVC中的ViewComponent中传递4个以上的参数 - How to pass more than 4 parameters in a ViewComponent in ASP.NET Core MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM