I am currently manually processing the "model" data as a string, but this is quite hacky. What do I need to do differently to get the controller action to properly deserialize the model data?
I have a fairly complex model:
public class NetControlModel: INetControlScript
{
public Guid NetId { get; set;}
public Guid NetControlScriptId { get; set; }
public INetScript Script { get; set; }
public INetCheckIns CheckIns { get; set; }
public NetControlModel(){
this.CheckIns = new CheckInModel();
}
}
Where the implementations of the Interfaces are as follows:
public class NetControlScript: INetScript
{
public IScriptBanner Banner { get; set; }
public IScriptAnnouncements Announcements { get; set; }
public IScriptBody Body { get; set; }
}
public class NetControlBanner: IScriptBanner
{
public string ScriptBanner { get; set; }
}
public class NetControlAnnouncements: IScriptAnnouncements
{
public string ScriptAnnouncements { get; set; }
}
public class NetControlBody: IScriptBody
{
public string ScriptBody { get; set; }
}
and
public class CheckInModel: INetCheckIns
{
public IEnumerable<ICheckIn> CheckInCollection { get; set; }
public CheckInModel()
{
this.CheckInCollection = new List<CheckIn> ();
}
}
public class CheckIn : ICheckIn
{
public Guid NetId{ get; set; }
public int CheckInId { get; set; }
public string CallSign {get; set;}
public bool ShortTime {get; set;}
public bool Secured {get; set;}
public bool Comment {get; set;}
public bool Question {get; set;}
public DateTime FirstCheckIn { get; set;
}
public DateTime LastCheckIn { get; set;
}
public Int16 TotalCheckIns { get; set; }
public string Notes { get; set; }
}
The View is 2 parts, one consisting of essentially an input form, with a partial at the bottom that I intend to be a list of records that have already been entered using the input fields. The Parent form and nested partial are declared as follows:
@using NetControl.Domain.Models
@model NetControlModel
@using (Ajax.BeginForm("SubmitStationCheckin", "NetControlScript", new
AjaxOptions { HttpMethod="POST"}))
{
@Html.HiddenFor(m => m.NetId)
@Html.HiddenFor(m => m.NetControlScriptId)
@Html.HiddenFor(m => m.CheckIns.CheckInCollection)
<div class="row">
<div class="col-md-2">
<div class="form-group">
@Html.Label("Call Sign")
@Html.TextBox("callSign", "callsign", new {@class= "form-control"})
</div>
</div>
<div class="col-md-1">
<div class="form-group">
@Html.Label("Short Time")
@Html.CheckBox("shortTime", false)
</div>
</div>
<div class="col-md-1">
<div class="form-group">
@Html.Label("Secured")
@Html.CheckBox("secured", false)
</div>
</div>
<div class="col-md-1">
<div class="form-group">
@Html.Label("Comment")
@Html.CheckBox("comment", false)
</div>
</div>
<div class="col-md-1">
<div class="form-group">
@Html.Label("Question")
@Html.CheckBox("question", false)
</div>
</div>
<div>
<input id="clickme" value="send it" type="button"/>
</div>
</div>
}
<div id="checkinList">
@{Html.RenderPartial("~/Views/NetControlScript/CheckinList.cshtml", Model.CheckIns);}
and the partial view:
@{
var CheckIn = Model.CheckInCollection.ToArray();
}
<div id="checkInListHidden">
<table id="hiddenTable">
@for(int i = 0; i < CheckIn.Count(); i++)
{
<tr>
<td> @Html.HiddenFor(m => CheckIn[i].CallSign) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].ShortTime) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].Secured) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].Comment) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].Question) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].LastCheckIn) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].FirstCheckIn) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].TotalCheckIns) </td>
<td> @Html.HiddenFor(m=> CheckIn[i].Notes) </td>
</tr>
}
< /table>
</div>
<div class="row">
<div class="col-md-2">Callsign</div>
<div class="col-md-1" >Short Time</div>
<div class="col-md-1">Secured</div>
<div class="col-md-1">Comment</div>
<div class="col-md-1">Question</div>
<div class="col-md-1">Last Check In</div>
<div class="col-md-1">First Checkin In</div>
<div class="col-md-1">Total Checkins</div>
<div class="col-md-2">Notes</div>
</div>
@foreach(CheckIn c in Model.CheckInCollection)
{
<div class="row">
<div class="col-md-2">
@Html.TextBoxFor(n => c.CallSign, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.ShortTime, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.Secured, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.Comment, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.Question, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.LastCheckIn, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.FirstCheckIn, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.TotalCheckIns, new {@class="form-control"})
</div>
<div class="col-md-1">
@Html.TextBoxFor(n => c.Notes, new {@class="form-control"})
</div>
</div>
}
Im posting the model data as well as the current data from the inputs to the controller using ajax as follows:
$.ajax({
type: "POST",
url: '/NetControlScript/SubmitStationCheckin',
//data: JSON.stringify({model: data, NetScriptId: netControlScriptId, NetId: netId, callSign: callSign, shortTime: shortTime, secured: secured, comment: comment, question: question}),
dataType: "html",
data: JSON.stringify({model: d, NetScriptId: netControlScriptId, NetId: netId, callSign: callSign, shortTime: shortTime, secured: secured, comment: comment, question: question}),
contentType: "application/json; charset=utf-8",
success: function (response) {
alert("Success response:" + response)
console.log("response" + response);
$('#checkinList').html(response)
},
failure: function (response) {
alert("Failure response:" + response);
},
error: function (response) {
alert("Error response:" + response);
$('#checkinList').html(response);
}
});
Here is the problem, I can see the model data being posted in fidler as a string of the type [[row 1 fields,...],[row 2 fields...]]. The individual items are hitting the controller (callsign, shortime, etc...) but the model is not getting deserialized into the model specified in the controller param.
[HttpPost]
public async Task<ActionResult> SubmitStationCheckin(NetControlModel model,Guid NetScriptId, Guid NetId, string callSign, bool shortTime, bool secured, bool comment, bool question )
{
... controller body
}