Reputation: 1236
*I have Model Class like:*
public class Timesheetmodel
{
ResLandEntities res = new ResLandEntities();
public int WEEK_CAL_ID { get; set; }
public int COMP_ID { get; set; }
public int RES_ID { get; set; }
public int PROJ_ID { get; set; }
public string DESCR { get; set; }
public int SUN_HRS { get; set; }
public int MON_HRS { get; set; }
public int TUE_HRS { get; set; }
public int WED_HRS { get; set; }
public int THU_HRS { get; set; }
public int FRI_HRS { get; set; }
public int SAT_HRS { get; set; }
public string IS_DELETED { get; set; }
public string CR_BY { get; set; }
public DateTime DT_CR { get; set; }
public string MOD_BY { get; set; }
public DateTime DT_MOD { get; set; }
public List<Timesheetmodel> GetTimeSheetDetails { get; set; }
}
in View :
<table id="dataTable" style="width: 80%; border: none">
<tbody>
@for (int i = 1; i <=Convert.ToInt32(Session["count"]); i++)
{
<tr>
<td style="width: 100px">
@* @Html.DropDownListFor(m => m.GetTimeSheetDetails[i].PROJ_ID, (SelectList)Model.getprojects(), "--Choose Your Project--")*@
</td>
<td>
@Html.TextBox("txtTask")
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].SUN_HRS, new { style = "width:50px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].MON_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].TUE_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].WED_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].THU_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].FRI_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
@Html.TextBoxFor(m => m.GetTimeSheetDetails[i].SAT_HRS, new { style = "width:90px; height:30px;" })
</td>
<td>
<input type="image" src="~/Img/delete.PNG" value="Delete Row" onclick="deleteRow(this)" style="margin-top: 5px;" />
</td>
</tr>
}
<tr>
<td>
<input type="submit" value="Update" class="btnstyle" name="btn" />
</td>
</tr>
</tbody>
</table>
and In Contoller:
[HttpPost]
public ActionResult Timesheet(string btn, Timesheetmodel objts)
{
TIMESHEET ts = new TIMESHEET();
if (btn == "Update")
{
foreach (var item in objts.GetTimeSheetDetails)//Getting Error Here as Object is not set to reference of the object.
{
item.PROJ_ID = ts.PROJ_ID;
item.DESCR = ts.DESCR;
ts.SUN_HRS = item.SUN_HRS;
ts.MON_HRS = item.MON_HRS;
ts.IS_DELETED = "N";
ts.TUE_HRS = item.SAT_HRS;
ts.SAT_HRS = item.SAT_HRS;
ts.SAT_HRS = item.SAT_HRS;
ts.SAT_HRS = item.SAT_HRS;
ts.SAT_HRS = item.SAT_HRS;
objTimeSheet.TIMESHEETs.Add(ts);
objTimeSheet.SaveChanges();
}
}
if (btn == "AddRecord")
{
int ses = Convert.ToInt32(Session["count"]);
ses++;
Session["count"] = ses;
}
return View();
}
I have set Everything perfectly , but showing error as
"Object reference is not set to reference of the object".
Where i have commit error. please any one help me.
Upvotes: 0
Views: 2350
Reputation: 12192
The problem is that you can't pass a list to the server like that. Essentially what you're doing is just rendering a textbox for each value in the list, but without an id let alone a unique id. In other words, the binding is lost once these text boxes are rendered. Form posts need to be sent back to the server as form data which are key value pairs; this design breaks that so your controller isn't able to bind/deserialize the values back into the viewmodel property, so it ends up null.
MVC can help you with this if you factor @Html.EditorFor(m => m.GetTimeSheetDetails) into your design. This will assign each control a unique ID in an expected format that can be passed to the action and be deserialized back into a proper list. This will complicate your table layout, but that can be solved with css.
Upvotes: 0
Reputation: 335
The model is being correctly bound to the action parameters on post with the
TextBoxFor( m => m.GetTimeSheetDetails[ i ].XXX_HRS
calls in the View-so there is not problems there.
Where the "Object reference not set to an instance of an object" error occurs for me is when the update button is clicked without there being any TimeSheetDetail inputs in the view (when Session[ "Count" ] == 0). The reason for this is that the DefaultModelBinder searches the POSTed form values for data to bind to the model but cannot find any as the inputs were not present in the view. Thus
objts.GetTimeSheetDetails
does not have any values bound to it and remains null.
I would suggest considering removing the update button in the View if there are no items with something like this
@if( 0 < Convert.ToInt32(Session[ "count" ] )
{
<tr>
<td><input type="submit" value="Update" class="btnstyle" name="btn" /></td>
</tr>
}
Upvotes: 1