0

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>
3
  • do you need to set content type to url encoded?? Commented May 14, 2014 at 9:03
  • 1
    have you tried just posting var data_to_send = ko.toJSON(self) Commented May 14, 2014 at 9:11
  • This Worked. but could you explain why it didn't work with 'ko.toJSON({value: self})' ? Also Post this as an answer so I can accept it. Commented May 14, 2014 at 10:07

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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) {
});

1 Comment

not solved the problem i tried both of our solutions but they didn't work. same null values for Person objects are shown..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.