'How to send list from view to controller MVC

I have view model:

public class AvailableTimesViewModel
{
    public AvailableTimesViewModel() { }

    public AvailableTimesViewModel(List<DateTime> list)
    {
        availableTimesList = new List<DateTime>();
        if (list != null && list.Any())
        {
            foreach (var l in list)
            {
                availableTimesList.Add(l);
            }        
        }
    }

    public List<DateTime> availableTimesList { get; set; }
}

My view:

@model ViewModels.AvailableTimesViewModel
@{
ViewBag.Title = "AvailableTimes";
}
<p>
 @Html.ActionLink("Create New", "Create")
 </p>
 <table class="table">

 List<DateTime>avTimes=new List<DateTime>
 @for (var i = 0; i < Model.availableTimesList.Count; i++)
 {
 <tr>
    <td>
        @Html.HiddenFor(x => x.availableTimesList[i])
        @Model.availableTimesList[i].TimeOfDay
        @Html.ActionLink("Book", "BookVisit", new { date =   Model.availableTimesList[i].TimeOfDay, avTimes = Model.availableTimesList },null)   |
        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */    }) |
        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
    </td>

    </tr>
 }
 </table>

and controller:

public ActionResult BookVisit(DateTime date,List<DateTime> avTimes)
    {
        return View();
    }

Question is: how to send second argument from ActionLink(avTimes=Model.availableTimesList) to controller. In other words - how to send list rendered in the view to the controller.



Solution 1:[1]

First of all, you do not need to initialize or define avTimes before passing it as route data value. This line is not needed:

List<DateTime>avTimes = new List<DateTime>

That being said, you cannot pass collections as Route Data values - it does not work and is not best practice anyway.

Since @Html.ActionLink produces link like http://domainname.com/bookvisit/book?abc=1&bcd=ldf&ctf=5, I don't think it's a good practice to have a full list values appended in the url.

What you are trying to do can be achievable this way:

@{var myObjectWrapper = new MyObjectWrapper(){Data = @Model.availableTimesList };}

@Html.Action("Book", "BookVisit", 
            new { date =   Model.availableTimesList[i].TimeOfDay, avTimes = myObjectWrapper } ,null)

And your action method:

public ActionResult BookVisit(DateTime date, MyObjectWrapper  avTimes)
{
    vat myList = avTimes.Data;
    return View();
}

Hope that helps.

Solution 2:[2]

Add your "list" to the AvailableTimesViewModel

 public class AvailableTimesViewModel
{
    public string MyFirstProperty { get; set; }
    public List<DateTime> availableTimesList { get; set; }
}

Then pass this as your model.

You should also use a partial view to display your Available Times too.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sv__t
Solution 2 Mark