Pregunta

So I have a ViewModel:

public class PrelimViewModel
    {
        public int? PrelimId { get; set; }
        public int JobId { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }
        public string Comment { get; set; }
        public string Unit { get; set; }
        public int? Qty { get; set; }
        public decimal? BidPrice { get; set; }
        public bool Accepted { get; set; }
        public int? OriginalPrelimId { get; set; }
        public string Option { get; set; }
        public List<RefCodeViewModel> Codes { get; set; }
        public List<UnitViewModel> Units { get; set; }
        public List<OptionLetterViewModel> Options { get; set; }
    }

A GetPrelim controller method that returns List<PrelimViewModel>

A ko.mapper of the List of PrelimViewModel client side:

 viewModel = ko.mapping.fromJS({ Prelims: data });
                ko.applyBindings(viewModel);

Do some work, ready to save:

  function savePrelims(elem) {
            var $form = $(elem).parents('form');

            $.ajax({
                url: $form.attr('action'),
                type: "POST",
                data: ko.toJSON(viewModel),
                datatype: "json",
                contentType: "application/json charset=utf-8",
                success: function(data) { toastr.success('Options Saved!'); },
                error: function(data) { }
            });
}

And I cannot get my MVC Method to parse the JSON:

public void AddPrelims(List<PrelimViewModel> Prelims)
¿Fue útil?

Solución

You have wrapped your list into the Prelims property in your KO viewmodel, but on the server side you are expecting just a list not with an object which has the list in its Prelims property.

So to fix this you just need to send the list in your ajax request:

data: ko.toJSON(viewModel.Prelims()),

However you don't necessary need to wrap your list if you won't have any additional properties on your viewmodel, because you can just do:

viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);

And then in your view you can bind to $data which is refering the current viewmodel which will be your array:

<div data-bind="foreach: $data">
   ...
</div>

And in this case you don't have to change your ajax call and data: ko.toJSON(viewModel), should work fine.

However this foreach: $data is kinda strange and it is not the best solution so you are probably better if you stick to your original approach with ko.mapping.fromJS({ Prelims: data }); and sending the correct data back to your controller.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top