Search code examples
c#asp.net-mvc-4razorvisual-studio-2012asp.net-mvc-viewmodel

Returning viewmodel from view gives an ampty object in the controller


I'm working on a small project. The intention is to maintain the presences of a couple of users on some specific dates. This dates are first chosen by the user.

Therefor I use a view model. This will provide all possible data with a check box in a table to show to the user.

In the view itself I walk every day in the given view modeland I let the view generate a tag and an editor object (Html.EditorFor ()). All this is surrounded by the form creation (@ Html.BeginForm ()). Rendering the view is not the problem.

The problem is when I try to return the view model. The viewmodel object that I receive is an object with null - objects in themselves. Like it has been created by the default constructor.

Controller:

[HttpGet]
    public ActionResult OpldagenLt()
    {
        var lt = _gebruikerRepository.GeefTraject(_gebruikerRepository.TrajectId);
        List<DatumModel> data = new List<DatumModel>();
        foreach (Opleidingdag opldag in lt.GeefOpleidingdagenKleinerDanOfGelijkAanVandaag())
            data.Add(new DatumModel(opldag));

        List<ToekomstModel> toekomst = new List<ToekomstModel>();
        foreach (Opleidingdag opldag in lt.GeefOpleidingdagenGroterDanVandaag())
            toekomst.Add(new ToekomstModel(opldag));

        DataModel datamod = new DataModel();
        datamod.Datums = data;
        datamod.Toekomst = toekomst;

        if (lt.ControleerAantalOpleidingdagen())
        {
             _gebruikerRepository.GekozenDagen = GekozenDagen(datamod) as List<Opleidingdag>;
            return RedirectToAction("Index", "Aanwezigheid");
        }
        return View(datamod);
    }

    [HttpPost]
    public ActionResult OpldagenLt(DataModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        _gebruikerRepository.GekozenDagen = GekozenDagen(model) as List<Opleidingdag>;

        return RedirectToAction("Index", "Aanwezigheid");
    }

    public ICollection<Opleidingdag> GekozenDagen(DataModel datamod)
    {
        List<Opleidingdag> dagen = new List<Opleidingdag>();
            foreach (DatumModel datum in datamod.Datums)
            {
                dagen.Add(datum.Dag);
            }
        return dagen;
    }

View:

@using(@Html.BeginForm( "OpldagenLt", "Leertraject", FormMethod.Post))
{
<div>
    <table>
        <tr>
            <th colspan="2">reeds begonnen dagen</th>
        </tr>
        @foreach (var item in @Model.Datums)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => item.Dag.Dag.Day)/@Html.DisplayFor(modelItem => item.Dag.Dag.Month)/@Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
                <td>@Html.EditorFor(modelItem => item.Checked)</td>
            </tr>
        }
    </table>
</div>
<div id="toekomst">
    <table>
        <tr>
            <th>Dagen in de toekomst</th>
        </tr>
        @foreach (var item in @Model.Toekomst)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => item.Dag.Dag.Day)/@Html.DisplayFor(modelItem => item.Dag.Dag.Month)/@Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
            </tr>
        }
    </table>
</div>
<div>
    <p><input type="submit" value="Volgende"/></p>
</div>
}

Model:

using System;
using System.Collections.Generic;
using ProjectII.Models.domain;

namespace ProjectII.Viewmodels
{
public class DataModel
{
    public  DataModel()
    {
        Datums = new List<DatumModel>();
    }

    public ICollection<DatumModel> Datums { get; set; }
    public ICollection<ToekomstModel> Toekomst{ get; set; }
}

public class DatumModel
{
    public DatumModel()
    {
        Dag = new Opleidingdag(new DateTime().Date);
        Checked = true;
    }
    public DatumModel(Opleidingdag opldag)
    {
        Dag = opldag;
        Checked = true;
    }

    public Opleidingdag Dag { get; set; }
    public bool Checked { get; set; }
}

public class ToekomstModel
{
    public ToekomstModel()
    {
        Dag = new Opleidingdag(new DateTime().Date);
    }
    public ToekomstModel(Opleidingdag opldag)
    {
        Dag = opldag;
    }

    public Opleidingdag Dag { get; set; }
}
}

Thanks in advance for the help


Solution

  • @stephen: thanks for the help. with keeping your answer in my mind I finally succeeded returning those data.

    I changed the foreach into a for and changed ICollection to a List

    Model:

    using System;
    using System.Collections.Generic;
    using ProjectII.Models.domain;
    
    
    namespace ProjectII.Viewmodels
    {
    public class DataModel
    {
        public List<DatumModel> Datums { get; set; }
        public List<ToekomstModel> Toekomst{ get; set; }
    }
    
    public class DatumModel
    {
        public DatumModel()
        {
            Dag = new Opleidingdag(new DateTime().Date);
            Checked = true;
        }
        public DatumModel(Opleidingdag opldag)
        {
            Dag = opldag;
            Checked = true;
        }
    
        public Opleidingdag Dag { get; set; }
        public bool Checked { get; set; }
    }
    
    public class ToekomstModel
    {
        public ToekomstModel()
        {
            Dag = new Opleidingdag(new DateTime().Date);
        }
        public ToekomstModel(Opleidingdag opldag)
        {
            Dag = opldag;
        }
    
        public Opleidingdag Dag { get; set; }
    }
    }
    

    view:

    @model ProjectII.Viewmodels.DataModel
    
    @using(@Html.BeginForm())
    {
    <div>
        <table>
            <tr>
                <th colspan="2">reeds begonnen dagen</th>
            </tr>
    
             @for (int i = 0; i < Model.Datums.Count; i++)
           {
                <tr>
                    <td>@Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Day)/@Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Month)/@Html.DisplayFor(modelItem => Model.Datums[i].Dag.Dag.Year)</td>
                    <td>
                         @Html.EditorFor(modelItem => Model.Datums[i].Checked)
                    </td>
                </tr>
            }
        </table>
    
        @*@for (int i = 0; i < Model.Datums.Count; i++)
        {
            <div> @Html.DisplayFor(x => Model.Datums[i].Dag.Dag) 
                @Html.CheckBoxFor(x => Model.Datums[i].Checked) </div>
        }*@
    
    </div> 
    <div id="toekomst">
        <table>
            <tr>
                <th>Dagen in de toekomst</th>
            </tr>
            @foreach (var item in @Model.Toekomst)
            {
                <tr>
                    <td>@Html.DisplayFor(modelItem => item.Dag.Dag.Day)/@Html.DisplayFor(modelItem => item.Dag.Dag.Month)/@Html.DisplayFor(modelItem => item.Dag.Dag.Year)</td>
                </tr>
            }
        </table>
    </div>
    <div>
        <p><input type="submit" value="Volgende"/></p>
    </div>
    }
    

    Now I recieve a model with the right values

    thanks for the help people