How share ViewData between ViewComponent in Asp.net core
asp.net-core, asp.net-core-viewcomponent, c#, viewdata
Solution
`ViewData` is just like `ViewBag`. You use it only if you want to transfer data from Controller to View. For this I always prefer 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
Install-Package Microsoft.AspNetCore.Mvc.ViewFeatures
In your `Startup` class, add this line
services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
to your `ConfigureServices` method. I use `CookieTempDataProvider` as impelmentation of `ITempDataProvider` but you can use `SessionStateTempDataProvider`.
To store data into `TempData` dictionary you use this code:
this.TempData["data"] = "my value";
To retrieve data from `TempData` you use this code:
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. In your view component class, store your data in `HttpContext.Items` dictionary like this:
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:
- `HttpContext.Items` is cleared when the request ends.
- By default `TempData` is cleared when the data is read. To retain the data you need to explicitly call `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.
Problem
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. ``` 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(); } } ```