Question

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

Was it helpful?

Solution 2

@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

OTHER TIPS

With the way you construct your view, the ModelBinder cannot differantiate between the different elements in the list, and doesn't recognize them as items in the list. Try constructing the view like this:

@{ int datumteller = 0; }
 @foreach (var item in @Model.Datums)
 {
        <tr>
            <td>@Html.DisplayFor(modelItem => @Model.Datums[datumteller].Dag.Dag.Day)/@Html.DisplayFor(modelItem => @Model.Datums[datumteller].Dag.Dag.Month)/@Html.DisplayFor(modelItem => @Model.Datums[datumteller].Dag.Dag.Year)</td>
            <td>@Html.EditorFor(modelItem => @Model.Datums[datumteller].Checked)</td>
        </tr>
 datumteller++;
 }

@{ int toekomstteller = 0; }
 @foreach (var item in @Model.Toekomst)
 {
        <tr>
            <td>@Html.DisplayFor(modelItem => @Model.Toekomst[toekomstteller].Dag.Dag.Day)/@Html.DisplayFor(modelItem => @Model.Toekomst[toekomstteller].Dag.Dag.Month)/@Html.DisplayFor(modelItem => @Model.Toekomst[toekomstteller].Dag.Dag.Year)</td>
        </tr>
  toekomstteller++
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top