Fede
Fede

Reputation: 27

C# MVC - View returns Model null on Postback

I have absolutely no idea of why the model is null after submitting the form.....I have checked the FormCollection, but it only contains "ScriptAssignments.Assigned". Im using a strongly typed view, and im using a beginform....I don't get whats wrong here...I will appreciate any help.

This is how the View looks like.....

@model Models.ScriptAssignmentMatrix

@{
   ViewBag.Title = "Script Matrix";
}

<link href="@Url.Content("~/Content/RotatedHeaders.css")" rel="stylesheet" type="text/css" />

<h1>Assignment Matrix</h1>

@using (Html.BeginForm("SaveChanges", "ScriptMatrix",FormMethod.Post)) {
<div style=" height:15px"></div>    
<table class="table table-striped table-header-rotated">
   <thead>
      <tr>
        <th></th> 
        @foreach (var header in Model.ColumnHeaders) 
        {
            <th>
                <div class="container"><div class="head"><div class="vert">
                    <span style="font-size: 10pt">
                        @Html.DisplayFor(modelItem => header)
                    </span>
                </div></div></div>
            </th>
        }
      </tr>
    </thead>

    <tbody>

    @foreach (var row in Model.RowHeaders)
    {
        <tr>
            <td>
                <span style="font-size: 10pt; background: #eee; ">
                    @Html.DisplayFor(modelItem => row)
                </span>
            </td>
            @foreach (var header in Model.ColumnHeaders)
            {
                var ScriptAssignments = (from y in Model.ScriptAssignments
                               where y.AgentName == row && y.ScriptName == header
                               select y).First();
                <td>     
                    @Html.CheckBoxFor(Assignment => ScriptAssignments.Assigned) 
                </td>
            }
        </tr>

    }
    </tbody>

</table>

<div style=" height:30px"></div>    
<input type="submit" value="Save Changes" />
<div style=" height:30px"></div>    
 @ViewBag.Result

}

This is the Controller:

    [HttpPost]
    public ViewResult SaveChanges(ScriptAssignmentMatrix model)
    {

        ViewBag.Result = "Your changes have been saved";
        return View("Index", model);
    }

This is the ScriptAssignmentMatrix class:

public class ScriptAssignmentMatrix
{
    public List<ScriptAssignmentMatrixElement> ScriptAssignments { get; set; }
    public List<String> ColumnHeaders { get; set; }
    public List<String> RowHeaders { get; set; }
}

public class ScriptAssignmentMatrixElement
{
    public int ScriptId { get; set; }
    public string  ScriptName { get; set; }

    public int AgentId { get; set; }
    public string AgentName { get; set; }

    public bool Assigned { get; set; }
}

Upvotes: 1

Views: 828

Answers (2)

Fede
Fede

Reputation: 27

So I finally found the answer....still cant explain why.....but this is the working modified code of the view.....

Thanks gunr2171 and Jorge F....your comments put me in the right track.....

Models.ScriptAssignmentMatrix

@{
    ViewBag.Title = "Script Matrix";
}

<link href="@Url.Content("~/Content/RotatedHeaders.css")" rel="stylesheet" type="text/css" />

<h1>Assignment Matrix</h1>

@using (Html.BeginForm("SaveChanges", "ScriptMatrix",FormMethod.Post)) {

<div style=" height:15px"></div>    
<table class="table table-striped table-header-rotated">
   <thead>
      <tr>
        <th></th> 
        @foreach (var header in Model.ColumnHeaders) 
        {
            <th>
                <div class="container"><div class="head"><div class="vert">
                    <span style="font-size: 10pt">
                        @Html.DisplayFor(modelItem => header)
                    </span>
                </div></div></div>
            </th>
        }
      </tr>
    </thead>

    <tbody>

    @for (int row = 0; row < Model.RowHeaders.Count; row++ )
    {
        <tr>
            <td>
                <span style="font-size: 10pt; background: #eee; ">
                    @Html.DisplayFor(modelItem => Model.RowHeaders[row])
                </span>
            </td>
            @for (int column = 0; column < Model.ColumnHeaders.Count; column++ )
            {

                for (int index = 0; index < Model.ScriptAssignments.Count; index++)
                {
                     if (Model.ScriptAssignments[index].AgentName == Model.RowHeaders[row] && Model.ScriptAssignments[index].ScriptName == Model.ColumnHeaders[column])
                     {
                        <td>     
                            @Html.CheckBoxFor(Assignment =>  Model.ScriptAssignments[index].Assigned) 
                            @Html.HiddenFor(x =>  Model.ScriptAssignments[index].AgentId)
                            @Html.HiddenFor(x =>  Model.ScriptAssignments[index].ScriptId)
                            @Html.HiddenFor(x =>  Model.ScriptAssignments[index].AgentName)
                            @Html.HiddenFor(x =>  Model.ScriptAssignments[index].ScriptName)
                        </td>                             
                         break;
                     }

                }                    
            }
        </tr>
    }
    </tbody>

</table>

<div style=" height:30px"></div>    

<input type="submit" value="Save Changes" />
<div style=" height:30px"></div>    
 @ViewBag.Result

}

Upvotes: 0

mrsrizan
mrsrizan

Reputation: 311

DisplayFor doesnot bind the control with the model. So the best way is to use HiddenFor.

@foreach (var header in Model.ColumnHeaders) 
{
    <th>
        <div class="container"><div class="head"><div class="vert">
            <span style="font-size: 10pt">
                @Html.DisplayFor(modelItem => header)
                @Html.HiddenFor(modelItem => header)
            </span>
        </div></div></div>
    </th>
}

Upvotes: 1

Related Questions