In this article we will learn how to post data to an MVC action using KnockoutJS.
In this demo application we will create a simple form for capturing product information like product code, product name, and price and submit this information to an MVC action.
Let's start by creating a demo application. I am using Visual Studio 2012 Ultimate edition for this demo.
1. Create a new MVC 4 web application project and select the Basic template.
2. Add a controller “HomeController” and “Index” view.
3. Now we will add the required scripts. Make the following changes in App_Start -> BundleConfig.cs and Views->Shared->_layout.chtml.
4. Now we will create a Product model and ProductViewModel. Create an App folder under the Scripts folder and add a product.js file and add the following code to it. Now we have a ProductViewModel with currentProduct property initialized with some test data.
Now we will bind the ProductViewModel with the view which is Index.chtml. We have made all the properties of the Product model and ProductViewModel observable so that whenever there is a change in the View it will automatically update the ViewModel. This is the beauty of the Knockout framework and that is why we call it a binding library.
5. Let's add the following markup into our Index.html.
We will look at the option (b) below.
8. Now the next task is to POST the changes to the MVC action on the click of the Save button. Let's create a method “saveProduct” in our view model and bind it with the onclick event of the Save button. Let's add the following code to product.js and index.chtml.
9. Now the next thing we need to do is to convert our view model object into a JSON object so that we can post it to an MVC action. To do this we will use the Knockout mapping plugin “knockout.Mapping 2.4.0” which is available as NuGet.
Go to "TOOLS" -> "Library Package Manager" -> "Package Manager Console".
Install the NuGet as shown below. It will add “knockout.mapping-latest.js” into the Script folder.
Add the “knockout.mapping-latest.js” into the existing knockout script bundle.
Now we are ready to use the knockout mapping plugin in our demo.
10. Now create the class ProductModel under the Model folder which should contain the same properties as the Product class in product.js. It will look as in the following:
Now create an Action called “SaveProduct” which should be called when we click on the “Save” button and we will use “ProductModel” as an input parameter.
Now go to the product.js and first convert the knockout model into JS then post it to the MVC action “SaveProduct”. Product.js will look like as below. We will use ko.utils.postJson function to post the JSON form of our production model to the MVC action.
Now if we run the application and hit “Save”, we should receive the data in the product model as a parameter in the “SaveProduct” action but we did not, we received NULL instead.
The reason is MVC default model binding is unable to de-serialize the Knockout model (in JSON format) into a ProductModel. So we will need to create a custom model binding attribute to de-serialize the knockout model into MVC ProductModel.
Now apply the attribute on SaveProduct action's input parameter and run the application again.
Now we are receiving the updated model in our MVC action.
So in this article we learned how to POST data to an MVC action using the knockout-mapping plugin and the custom model binding.