The knockout viewer model goes back to ASP.NET MVC in part - how to send a complete object?

The presence of these ASP.NET MVC view models:

public class User { public string Name { get; set; } public LabeledEmail LabeledEmail { get; set; } } public class LabeledEmail { public IList<ContactLabel> Labels; public IList<ContactEmail> Emails; } 

and knockout model:

  <script type="text/javascript"> $(function() { ko.applyBindings(viewModel); $("#profileEditorForm").validate({ submitHandler: function(form) { if (viewModel.save()) window.location.href = "/"; return false; } }); }); var viewModel = { Name: ko.observable("@Model.Name"), EmailLabels: ko.observableArray(@Html.Json(Model.LabeledEmail.Labels.Select(l => l.Name)) || []), Emails: ko.observableArray(@Html.Json(Model.LabeledEmail.Emails) || []), addEmail: function() { viewModel.Emails.push(@Html.Json(new ContactEmail())); }, removeEmail: function(eml) { viewModel.Emails.remove(eml); }, saveFailed: ko.observable(false), // Returns true if successful save: function() { var saveSuccess = false; viewModel.saveFailed(false); jQuery.ajax({ type: "POST", url: "@Url.Action("MyAction", "MyController")", data: ko.toJSON(viewModel), dataType: "json", contentType: "application/json", success: function(returnedData) { saveSuccess = returnedData.Success || false; viewModel.saveFailed(!saveSuccess); }, async: false }); return saveSuccess; } }; </script> 

Which correct message for the controller matches User.Name , but User.LabeledEmail empty. I have to flatten the model the way I do to be able to use lists separately elsewhere. I know that viewModel.Emails populates correctly when saved, but User.LabeledEmails somehow returns null.

It basically comes down to the purpose of Model.LabeledEmail.Emails viewModel.Emails , and the deal will be solved, it seems, but I don’t know how and cannot find suitable examples.

  • What mistake am i making and
  • How to do it right?

Thanks in advance.

+1
source share
1 answer

Your JSON data structure should match the structure of your C # classes, especially property names. So you need to send JSON that looks something like this:

 { Name: 'somename', LabeledEmail: { Labels: [ somelements ], Emails: [ someelements ] } } 

So change your data: ko.toJSON(viewModel),

 data: JSON.stringify({ Name: viewModel.Name(), LabeledEmail: { Labels: viewModel.EmailLabels(), Emails: viewModel.Emails() } }) 

Or just use the data in the same structure on both the client and the server ...

As a side note: in your C # models, to display the properties of an MVC model, you must have properties instead of fields so that:

 public class User { public string Name { get; set; } public LabeledEmail LabeledEmail { get; set; } } public class LabeledEmail { public IList<ContactLabel> Labels { get; set; } public IList<ContactEmail> Emails { get; set; } } 
+3
source

All Articles