Alice
Alice

Reputation: 21

Retrieving a List from TempData[] causes it to be null

I am trying to pass a List<int> from 2 methods in ASP.NET Core, using TempData[]. In the Category() method, when retrieving the information productID is null, while TempData["Products"] is not null and contains the 2 numbers I added earlier - 1,2.

public IActionResult Homepage()
{
    List<int> productIDs = new List<int> { 1, 2};
    TempData["Products"] = productIDs;
    return View();
}

public IActionResult Category(string categoryName)
{
    List<int> productIDs = TempData["Products"] as List<int>;
    return View();
}

Upvotes: 0

Views: 74

Answers (1)

Victor
Victor

Reputation: 8890

Some useful information about the TempData lifetime you can see in the documentation:

ASP.NET Core exposes the Razor Pages TempData or Controller TempData. This property stores data until it's read in another request. The Keep(String) and Peek(string) methods can be used to examine the data without deletion at the end of the request. Keep marks all items in the dictionary for retention

Therefore, here it is example how to use it in your case.

In the controller:

public IActionResult Homepage()
{
    List<int> productIDs = [1, 2];
    TempData["Products"] = productIDs;
    return View();
}

[HttpPost]
public IActionResult Category(string categoryName)
{
    var data = new List<int>();
    var key = "Products";
    if (TempData.ContainsKey(key) && TempData[key] is IEnumerable<int> productsid)
    {
        data = productsid.ToList<int>();
    }
     
    //... using the `data`

    return View();
}

The view side:

@{
    var key = "Products";
    var data = new List<int>();
    if (TempData.ContainsKey(key) && TempData[key] is IEnumerable<int> productsid)
    {
        data = productsid.ToList<int>();
    }
    TempData.Keep(key);
}
@using (Html.BeginForm("Category", "Home", new { categoryName = "some text" }))
{
    @* .... some code using the `data` *@
    <button type="submit" class="btn btn-primary">Save</button>
}

The second approach is to using the serialization. To compile code below it is necessary include the Newtonsoft.Json package to the project.

using Newtonsoft.Json;
public IActionResult HomePage()
{
    var key = "Products";
    List<int> productIDs = [1, 2];
    TempData[key] = JsonConvert.SerializeObject(productIDs);
    return View();
}

[HttpPost]
public IActionResult Category(string categoryName)
{
    var key = "Products";
    var data = TempData.ContainsKey(key) ? JsonConvert.DeserializeObject<List<int>>(TempData[key].ToString()) : [];            
    //...
    return View();
}

In the view:

@using Newtonsoft.Json;
@{
    var key = "Products";
    var data = TempData.ContainsKey(key)
    ? JsonConvert.DeserializeObject<List<int>>(TempData[key].ToString())
    : [];
    TempData.Keep(key);
}
....

This solution is especially useful when need to pass a complex object.

Upvotes: 1

Related Questions