Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TempData value implicitly cast from List<string> to string[] after RedirectToAction()

I am using TempData to allow error message to be displayed after a redirect. For compatibility, I am using a List<string> to add messages into a list of errors in NotificationHelper class:

if (TempData["errorNotification"] == null) {
    TempData["errorNotification"] = new List<string> {
        message
    };
} else {
    var data = (List<string>) TempData["errorNotification"];
    data.Add(message);
    TempData["errorNotification"] = data;
}

Inside the controller, I fill that TempData with an error message and before the return RedirectToAction() call, TempData contains a dictionary record with List<string> (To be exact: System.Collections.Generic.List`1[System.String]) as a value but right after the call, inside Terms() function, the value becomes an array (System.String[]).

[HttpGet]
public IActionResult Terms()
{
    return View();
}

[HttpGet]
public IActionResult Index()
{
    NotificationHelper.AddErrorNotification("error!", TempData);
    return RedirectToAction("Terms");
}

The issue is that in order to use the data, I am casting the type in the view like so:

var errorMessages = TempData["errorNotification"] as List<string>;

and after the conversion I have to do this instead:

var errorMessages = TempData["errorNotification"] as string[];

One of above casts will come back as null, because of expecting a wrong type (depending on if I try to render the view before or after the redirect). Is that a desired behavior of TempData? How can I make sure that the view can expect one specific type being provided?

like image 600
m3h0w Avatar asked Mar 08 '23 12:03

m3h0w


2 Answers

I ended up going with using IEnumerable, as @Stephen Muecke suggested since I was only looking for iterating over the data and not extending or changing it.

So in the view instead of trying to guess if it's a list or an array, I used IEnumerable to account for both:

var errorMessages = TempData["errorNotification"] as IEnumerable<string>;
like image 175
m3h0w Avatar answered Apr 08 '23 09:04

m3h0w


Serialize your list of strings before assigning it to the TempData if you want to persist the type, and then deserialize it on retrieval. That's what I ended up doing. Though in my case I ended up storing a list of NotifyEntry instead of a list of string.

public class NotifyEntry
{
    public NotifyType Type { get; set; }
    public string Text { get; set; }
}

public enum NotifyType
{
    Success,
    Information,
    Warning,
    Error
}
like image 33
Nick Albrecht Avatar answered Apr 08 '23 09:04

Nick Albrecht