0

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
 }
Enoch_Root
  • 21
  • 2
  • All you need to show us in your question is 1. Exact content of what you are posting. 2. What it should convert to. You are showing 2 but not 1. You can make your question clear by removing everything else. – CodingYoshi Oct 14 '17 at 13:26
  • Start by reading [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) to understand how to generate a view for collection items and how the `name` attributes must match your model. And when you generate you view correctly, its just `dataL $('form').serialize()` and remove the `contentType` option in your ajax call. –  Oct 14 '17 at 20:37
  • If you still need help please post the raw posted body from Fiddler here. It will be easier for us to point you to the problem then. But I bet @StephenMuecke is right with his educated guess that the way you build up your postback payload does not match to what the model binder expects. – Peit Oct 16 '17 at 08:15

0 Answers0