0

I am following a simple video tutorial for Knockout.js by Steve Sanderson: http://channel9.msdn.com/Events/MIX/MIX11/FRM08

At the very end of it he performs an AJAX call to show how can you use knockout to process data on the server. I repeat all of what he is doing, but for some reason my JSON object doest bind to a POCO class correctly. This is an object I send from the view:

{"firstName":"Bartosz","lastName":"Malinowski","friends":[{"name":"Zofia"},{"name":"Zenon"}],"fullName":"Bartosz Malinowski"}

and then use this code to read it in the controller:

public JsonResult Save(Person person)
    {
        var message = string.Format("Saved {0} {1}", person.firstName, person.lastName);

        return Json(new { message });
    }

    public class Person 
    {
        public string firstName { get; set; }
        public string lastName { get; set; }
        public string fullName { get; set; }
        public ICollection<Friend> friends { get; set; }
    }

    public class Friend
    {
        public string Name { get; set; }
    }
}

My code on the client side looks like this:

'@{
    ViewBag.Title = "Home Page";
}

<script src="../../Scripts/jquery.tmpl.js" type="text/javascript"></script>

<p>First name: <input data-bind="value: firstName"/></p>
<p>Last name: <input data-bind="value: lastName"/></p>

<p>Full name: <span data-bind="text: fullName"></span></p>

<h2>Friends (<span data-bind="text: friends().length"></span>)</h2>
<ul data-bind="template: { name: 'friendsTemplate', foreach: friends }"></ul>

<script id="friendsTemplate" type="text/html">
    <li>
    <input data-bind="value: name"/>
    <button data-bind="click: remove">Remove</button></li>

</script>

<button data-bind="click: addFriend, enable: friends().length < 5">Add Friend</button>
<button data-bind="click: save">Save</button>

<script type="text/javascript">
    function friend(name) {
        return {
            name: ko.observable(name),
            remove: function () {
                viewModel.friends.remove(this);
            }
        };
    }

    var viewModel = {
        firstName: ko.observable("Bartosz"),
        lastName: ko.observable("Malinowski"),
        friends: ko.observableArray([new friend("Zofia"), new friend("Zenon")]),
        addFriend: function () {
            this.friends.push(new friend("Jan"));
        },
        save: function () {
            $.ajax({
                url: "@Url.Action("Save")",
                type: "post",
                data: ko.toJSON(this),
                contenttype: "application/json",
                success: function (result) { alert(result.message) }
            });
        }
    };
    viewModel.fullName = ko.dependentObservable(function () {
        return this.firstName() + " " + this.lastName();
    }, viewModel);

    ko.applyBindings(viewModel);
</script>

When I run it in debug mode and check person in the Save method parameter I've got null value for each Person property. So it just doesn't bind to me??

2
  • 1
    Also, when you say 'doest bind to a POCO class correctly', does that mean that some of the fields bind? Commented Nov 14, 2012 at 10:48
  • Thanks for an answer, I have added my code from the client side to the original question. Commented Nov 14, 2012 at 13:49

1 Answer 1

1

I do exactly the same here is my code

 $.ajax({
                url: url,
                type: "POST",
                dataType: "json",
                data: ko.toJSON(viewModel),
                contentType: 'application/json; charset=utf-8',
                success: function (returnedData)
                {
                    window.location.replace(urlRedirect);
                }
            });

There is a few differences : dataType and the charset, I'd say that it's the dataType.

I also have the [HttpPost] on my action.

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

1 Comment

Yes, it was a typo in the contenttype which should be contentType. I just couldn't spot it. Thanks

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.