[RESOLVED]List<string> passed in ViewBag gets with “System.Collections.Generic.List`1[System.String]”

I have a link to another controller and I want to pass a list of strings.

FirstController.cs

I have list of records in table with checkbox in each row, List of string values are selected by checking the checkbox.

public ActionResult Select(bool isChecked, String id)
        {
            var selectList = (List<String>)HttpContext.Session["SelectList"] ?? new List<String>();
            if (isChecked && !selectList.Contains(id))
            {
                selectList.Add(id);
            }
            else if (!isChecked && selectList.Contains(id))
            {
                selectList.RemoveAll(s => s == id);
            }
            ViewBag.selectList = selectList;
            return Content("OK");
        }

This list of string values i am passing to another SecondController.cs using ‘ViewBag’

public ActionResult AddSitesToUser(string returnUrl,string selectList, int userId = 0)
        {
            ViewBag.selectList = selectList;
}

My View:

(Html.BeginForm("AddSitesToUser", "User", new { returnUrl = ViewBag.returnUrl,selectList=((List<string>)ViewBag.selectList )})

In my FirstController.cs the list of ViewBag.selectList = selectList; created properly, but if i pass those list of strings to SecondController.cs instead of returning list of strings it gives me ‘"System.Collections.Generic.List1[System.String]"

Any idea on what I’m doing wrong?

Thanks

This is because you are using this within the RouteValues parameter of the BeginForm() method, which will populate QueryString variables for the action attribute on the Form itself.

If you are storing a collection of strings within the ViewBag, ASP.NET isn’t going to know how to display this within the URL so it uses "System.Collections.Generic.List" as it was passed a string and that’s the only way it knows how to interpret it.

You might try storing a comma-delimited string within ViewBag which might be able to be passed along more easily as follows :

// When storing your values in the SelectList, consider using a comma-delimited string (e.g. "A,B,C,D,E,F")
ViewBag.selectList = String.Join(",",selectList.Items.Cast<string>().ToArray());

This will add this comma-delimited string to your form properly when it loads your selectList variable : 

(Html.BeginForm("AddSitesToUser", "User", new { returnUrl = ViewBag.returnUrl,selectList=ViewBag.selectList )})

Then when your AddSitesToUser method is posted to, you can pull your collection out of the QueryString and properly split it back into a collection :

public ActionResult AddSitesToUser(string returnUrl,string selectList, int userId = 0)
{
     // Retrieve your list
     List<string> list = selectList.Split(',').ToList();
}

Tried with your solution, but still showing same 

“System.Collections.Generic.List`1[System.String]”

That’s shouldn’t be happening, as the line where you actually set your ViewBag should store a string into it (and not a collection) :

ViewBag.selectList = String.Join(",",selectList.Items.Cast<string>().ToArray());

when you add routes values to the form, ToString() is called on the value to make it a string. for List<> (and most classes). the to string just returns the class name. you need to convert the list to a string value, that your controller can later parse.

Leave a Reply