Reputation: 21
Model: I have a view with collection of addresses and names. I know i am missing something but not able to figure out. I am new to knockout trying to create some sample from using mvc. I see null values coming in the controller. Here is the fiddle: https://jsfiddle.net/iamsrk/9kf41vd7/32/
public class PersonModel
{
public virtual ICollection<NameModel> NameModel { get; set; } = new HashSet<NameModel>();
public virtual ICollection<AddressModel> AddressModel { get; set; } = new HashSet<AddressModel>();
}
public class NameModel
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string Suffix { get; set; }
}
public class AddressModel
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string ReportingDate { get; set; }
public string Gender { get; set; }
public string Suffix { get; set; }
}
Controller Action:
public ActionResult GetPerson(PersonModel personModel)
{
return null;
}
View:
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading">
<h1 class="panel-title">
Names
</h1>
</div>
<div data-bind="with: nameModel" class="panel-body">
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>First</th>
<th>Middle</th>
<th>Last</th>
<th>Suffix</th>
<th>Gender</th>
</tr>
</thead>
<tbody data-bind="foreach: names">
<tr>
<td>
<input class="form-control" data-bind="value: firstName" />
</td>
<td>
<input class="form-control" data-bind="value: middleName" />
</td>
<td>
<input class="form-control" data-bind="value: lastName" />
</td>
<td>
<input class="form-control" data-bind="value: suffix" />
</td>
<td>
<input class="form-control" data-bind="value: gender" />
</td>
<td style="vertical-align: inherit;"><a href="#" data-bind="click:$parent.removeName.bind($data)">Delete</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-success btn-sm" data-bind="click: addName.bind($data)">Add Name</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-info">
<div class="panel-heading">
<h1 class="panel-title">
Addresses
</h1>
</div>
<div data-bind="with: addressModel" class="panel-body">
<table class="table table-hover table-responsive">
<thead>
<tr>
<th>street</th>
<th>city</th>
<th>state</th>
<th>country</th>
</tr>
</thead>
<tbody data-bind="foreach:names">
<tr>
<td>
<input class="form-control" data-bind="value: street" />
</td>
<td>
<input class="form-control" data-bind="value: city" />
</td>
<td>
<input class="form-control" data-bind="value: state" />
</td>
<td>
<input class="form-control" data-bind="value: country" />
</td>
<td style="vertical-align: inherit;"><a href="#" data-bind="click:$parent.removeAddress.bind($data)">Delete</a></td>
</tr>
</tbody>
</table>
<button class="btn btn-success btn-sm" data-bind="click: addAddress.bind($data)">Add Address</button>
</div>
</div>
</div>
</div>
<button id="saveButton" type="button" class="btn btn-primary btn-company pull-right" data-bind="click: save">
Save
<span class="glyphicon glyphicon-download-alt"> </span>
</button>
KnockOut Script:
<script>
var NameModel = function(names) {
var self = this;
self.addName = function() {
self.names.push({
firstName: "",
middleName: "",
lastName: "",
suffix: "",
gender: ""
});
};
self.removeName = function(name) {
self.names.remove(name);
};
if (names != null)
self.names(names);
};
var AddressModel = function(addresses) {
var self = this;
self.names = ko.observableArray(addresses);
self.addAddress = function() {
self.names.push({
street: "",
city: "",
state: "",
country: ""
});
};
self.removeAddress = function(address) {
self.names.remove(address);
};
if (addresses != null)
self.names(addresses);
};
var viewModel = {
nameModel: new NameModel([
{
firstName: "",
middleName: "",
lastName: "",
suffix: "",
gender: ""
}
]),
addressModel: new AddressModel([
{
street: "",
city: "",
state: "",
country: ""
}
]),
save: function () {
var self = this;
$.ajax({
url: '@Url.Action("GetPerson", "Person")',
type: 'POST',
contentType: 'application/json',
data: ko.toJSON({ PersonModel: self
})
});
}
};
ko.applyBindings(viewModel);
</script>
Upvotes: 0
Views: 81
Reputation: 7211
This
data: ko.toJSON({ PersonModel: self })
will send this
{ PersonModel: { nameModel: { names: [...] }, addressModel: { addresses: [...] } }
which does not match your C# classes. You want to send this
{ nameModel: [...], addressModel: [...] }
because in JSON the root object is not named and your C# class does not have a names
or addresses
property. Try
data: ko.toJSON({ nameModel: self.nameModel.names,
addressModel: self.addressModel.addresses })
Also, POSTing to a controller action called "GetPerson" is a really bad idea. And your address model has an observable array called names
, which I assume is a copy-paste error.
Upvotes: 1