Bob Cichon
Bob Cichon

Reputation: 209

Cannot get view with list (in object) selections to pass back to controller c#

Beginner who needs help!! I have passed in a list of items to a view. Works great. I want to select from this list with checkbox and then gather data and pass it back to the Controller for processing. I will loop through the selections in the controller and post appropriate data to the model. At this point, I have tried enumeration in many different ways and simply cannot figure it out how to build the model and pass the data back back. Please advise!!

The view: (hacked in in several formats, but this works to post the data on the view from the get in the controller)

View:

@model IEnumerable<eManager.Web2.Models.AddCompToEventClass>

@{
    ViewBag.Title = "AddCompToClass";
}

<h2>AddCompToClass</h2>
@using (Html.BeginForm("AddCompToClass", "Compeditor", FormMethod.Post))
{

    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

<table>

         @foreach (var item in Model)
         { 
     <tr>
        <td>
            @Html.DisplayFor(modelItem => item.CompLast)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Event_CompID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ClassName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CompeditorID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EventClassID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EventName)
        </td>
        <td>
            @Html.CheckBoxFor(modelItem => item.IsSelected)
        </td>

ViewModel feeding the above view: (Note: this is not data from an actual view, but a compound set of data gathered the controller get)

    {
    public class AddCompToEventClass
    {
        public int CompeditorID { get; set; }
        public int Event_CompID { get; set; }
        public string EventName { get; set; }
        public int EventClassID { get; set; }
        public string ClassName { get; set; }
        public int EventID { get; set; }
        public string CompLast { get; set; }
        public int CompEventID { get; set; }
        public bool IsSelected { get; set; }

    }
}

Here is the specific area of the Controller's HTTPPOST:

 [HttpPost]
   public ActionResult AddCompToClass(AddCompToEventClass[] viewModel) 
   {
       var eventclasscomp = new Event_Class_Compeditors();

       {
           if (ModelState.IsValid)

            foreach (AddCompToEventClass items in viewModel) ;

After I execute the FormSubmit, I can see a single set of all values come into the controller, but they are all null or zero. I pass an object with 2 sets and show it but cannot understand how to rebuild the model and send it back to the controller.

Upvotes: 0

Views: 2092

Answers (4)

OlegGuy
OlegGuy

Reputation: 41

If you want to use all items passing them through the view to another ActionResult you could use TempData like that:

public ActionResult Index()
    {
        MainViewModel model = new MainViewModel();
        model.Events = new List<AddCompToEventClass>();
        model.Events.Add(new AddCompToEventClass() { CompeditorID = 1, Event_CompID = 2, EventName = "rami" });
        model.Events.Add(new AddCompToEventClass() { CompeditorID = 3, Event_CompID = 4, EventName = "ramilu" });


        TempData["AllEvents"] = model.Events;


         return View(model);
    }

In your view for this case you don't need to populate each @Html.DisplayFor(modelItem => Model.Events[i].CompeditorID) @Html.HiddenFor(modelItem => Model.Events[i].CompeditorID)

you just could use that instead:

@using (Html.BeginForm("Submit", "Person", FormMethod.Post))
{
    @Html.AntiForgeryToken()


    <input type="submit" value="Add All Events" />
}

Then when we click on "Add All Events" button, it will hit following action -

    public ActionResult Submit(MainViewModel model)
    {
 var allEventsList = (List<AddCompToEventClass>)TempData["AllEvents"];

            foreach (var event in allEventsList)
            {
              //do somethig with all events

             }

        return View();
    }

Upvotes: 0

ramiramilu
ramiramilu

Reputation: 17182

Do like this. Lets say if your model is -

public class MainViewModel
{
    public List<AddCompToEventClass> Events { get; set; }
}
public class AddCompToEventClass
{
    public int CompeditorID { get; set; }
    public int Event_CompID { get; set; }
    public string EventName { get; set; }
}

And then your action which returns the display view -

    public ActionResult Index()
    {
        MainViewModel model = new MainViewModel();
        model.Events = new List<AddCompToEventClass>();
        model.Events.Add(new AddCompToEventClass() { CompeditorID = 1, Event_CompID = 2, EventName = "rami" });
        model.Events.Add(new AddCompToEventClass() { CompeditorID = 3, Event_CompID = 4, EventName = "ramilu" });
        return View(model);
    }

And then the View -

@model MVC.Controllers.MainViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm("Submit", "Person", FormMethod.Post))
{

    <table>
        @for (int i = 0 ; i < Model.Events.Count ; i++)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => Model.Events[i].CompeditorID)
                    @Html.HiddenFor(modelItem => Model.Events[i].CompeditorID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => Model.Events[i].Event_CompID)
                    @Html.HiddenFor(modelItem => Model.Events[i].Event_CompID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => Model.Events[i].EventName)
                    @Html.HiddenFor(modelItem => Model.Events[i].EventName)
                </td>
            </tr>
        }
    </table>
    <input type="submit" value="Save" />
}

Then when we click on submit button, it will hit following action -

    public ActionResult Submit(MainViewModel model)
    {
        return View();
    }

And when we debug all the values will be persisted -

enter image description here

Upvotes: 1

jarnail
jarnail

Reputation: 414

Please take a look at this post which explains the same scenario of passing back select values in checkboxlist to controller.

Upvotes: 0

Matt Tabor
Matt Tabor

Reputation: 1053

you are using DisplayFor in your view, this will only render labels, you are not sending anything back to the server.

put another row under your DisplayFor items with HiddenFor and these items will be posted back to the server. @Html.HiddenFor will render hidden inputs for these items and populate them with the values from your view model you are passing it.

Upvotes: 0

Related Questions