Pregunta

I am stucked on this problem since yesterday. I start learning knockoutjs with ASP.Net WebAPI. Everything work very well until i post the data back to the API Controller. everytime I paseed the data to the controller it shows null value for every field of the Person object.

enter image description here

I tried everything e.g. using $.ajax with contentType: 'application/json', or contentType: 'application/json, utf-8...' but nothing works for me. please give some solution i will be very thankful to you..

here is the code of WebAPI Post Method:

// POST api/some
public HttpResponseMessage Post([FromBody]Person value)
{
    repository.SavePerson(value);
    return Request.CreateResponse(HttpStatusCode.OK);
}

And here is Person class

public class Person
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public List<string> activities { get; set; }
    public string favoriteHobby { get; set; }
}

And here is javascript / knockout code

function PersonViewModel() {
    var self = this;

    self.firstName = ko.observable('');
    self.lastName = ko.observable('');
    self.activities = ko.observableArray([]);
    self.favoriteHobby = ko.observable('');

    self.loadUserData = function () {
        $.getJSON("api/Some/Get", function (data) {
            self.firstName(data.firstName);
            self.lastName(data.lastName);
            self.activities(data.activities);
            self.favoriteHobby(data.favoriteHobby);
        });
    }

    self.saveUserData = function () {
        var data_to_send = { value: ko.toJSON(self) };
        $.post("api/Some/Post", data_to_send, function (data) {
        });
    }
};

ko.applyBindings(new PersonViewModel());

And finally here is the HTML

<form action="#" method="post">
<p>
    First name:
    <input data-bind='value: firstName' />
</p>
<p>
    Last name:
    <input data-bind='value: lastName' />
</p>
<div>
    Your favorite food:
    <select data-bind='options: activities, value: favoriteHobby'>
    </select>
</div>
<p>
    <button data-bind='click: loadUserData'>Load Data</button>
    <button data-bind='click: saveUserData'>Save Data</button>
</p>
</form>
¿Fue útil?

Solución

If you want to post JSON like

{ "value" : {"firstName" : "Jane", "lastName" : "Doe" }  }

to an ApiController method, you need to add an additional "model" server side

public class ValueModel
{
    public Person value { get; set; }
} 

public class Person
{
    public string firstName { get; set; }
    public string lastName { get; set; }
    public List<string> activities { get; set; }
    public string favoriteHobby { get; set; }
}

public HttpResponseMessage Post([FromBody]ValueModel model) { .. }

Alternatively, drop the {"value": ..} in you JSON and just post var data_to_send = ko.toJSON(self)

This is because the model binder to bind the exact same "structure" of the JSON you post.

Otros consejos

The data you're sending isn't JSON; only the property value is. In order to get posting JSON working you should serialize the complete object to JSON and set the content type:

var data_to_send = ko.toJSON({ value: self });
$.ajax({
    url: "api/Some/Post",
    type: 'POST',
    data: data_to_send ,
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    async: false,
    success: function(data) {

    }
});

But you should also be able to post form data instead of JSON:

var data_to_send = { value: ko.toJS(self) };
$.post("api/Some/Post", data_to_send, function (data) {
});
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top