Introduction
This article shows Databinding and Templating using Knockout in the ASP.NET Web API. In this article we use the Knockout.js file. Knockout contains a JavaScript library and this library helps for creating a responsive display and editor user interface under laying of the data model.
Use the following procedure to create a sample.
Step 1
First we create a Web API application:
- Start Visual Studio 2012.
- From the Start window select "Installed" -> "Visual C#" -> "Web".
- Select "ASP.NET MVC4 Web Application" and click on the "OK" button.
![Select MVC4 Application]()
- From the MVC4 Project window select "Web API".
![Select Web API]()
- Click on the "OK" button.
Step 2
Create a Model class:
- In the "Solution Explorer".
- Right-click on the "Model" -> "Add" -> "Class".
- Select "Installed" -> "Visual C#".
![Create Model Class]()
- And then select "Class" and click on the "OK' button.
Add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Knockoutbinding.Models
{
public class Post
{
public int P_Id { get; set; }
public string P_Title { get; set; }
public string P_Post { get; set; }
public string P_Comments { get; set; }
public bool P_IsDeleted { get; set; }
}
}
Step 3
Now Rename "ValuesController" to "PostsController". This file exists in the "Controller folder".
Add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Knockoutbinding.Models;
using System.Web;
namespace Knockoutbinding.Controllers
{
public class PostsController : ApiController
{
List<Post> PostContext;
public PostsController()
{
if (HttpContext.Current.Application["postContext"] == null)
{
HttpContext.Current.Application["postContext"] = new List<Post>();
((List<Post>)HttpContext.Current.Application["postContext"]).Add(
new Post { P_Id = 1, P_Title = "Enter Title 1", P_IsDeleted = false, P_Post = "Post_No 1" });
((List<Post>)HttpContext.Current.Application["postContext"]).Add(
new Post { P_Id = 2, P_Title = "Enter Title 2", P_IsDeleted = false, P_Post = "Post_No 2" });
}
PostContext = (List<Post>)(HttpContext.Current.Application["postContext"]);
}
// GET api/values
public IEnumerable<Post> Get()
{
return PostContext;
}
// GET api/values/5
public Post Get(int id)
{
Post current = PostContext.Find(p => p.P_Id == id && !p.P_IsDeleted);
if (current == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
else
{
return current;
}
}
// POST api/values
public void Post([FromBody]Post value)
{
value.P_Id = PostContext.Count + 1;
PostContext.Add(value);
}
// PUT api/values/5
public void Put(int id, [FromBody]Post value)
{
Post current = PostContext.Find(p => p.P_Id == id);
if (current == null || current.P_IsDeleted)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
else
{
current.P_Title = value.P_Title;
current.P_Post = value.P_Post;
current.P_IsDeleted = value.P_IsDeleted;
}
}
// DELETE api/values/5
public void Delete(int id)
{
Post current = PostContext.Find(b => b.P_Id == id);
if (current == null || current.P_IsDeleted)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
else
{
current.P_IsDeleted = true;
}
}
}
}
Step 4
Now create a knockout.js file as in the following:
- In the "Solution Explorer".
- Right-click on the "Script" folder select "Add" -> "New Item".
- Then select "JavaScript". Click on the "Add" button.
![Create Knockout.js file]()
Add the following code:
var viewModel =
{
posts: ko.observableArray([]),
selectedPost: ko.observable(null),
selectPost: function (post) {
viewModel.selectedPost(this);
$(".right-section").show();
},
newPost: function () {
this.posts.push({
P_Title: ko.observable("New Post " + this.posts().length),
P_Id: ko.observable(this.posts().length+1),
P_Post: ko.observable("Post_No " + this.posts().length),
IsNew: ko.observable(true)
});
}
}
$(document).ready(function () {
$(".right-section").hide();
$.ajax(
{
url: "/api/Posts",
contentType: "text/json",
type: "GET",
success: function (data) {
$.each(data, function (index) {
viewModel.posts.push(toKoObserable(data[index]));
});
ko.applyBindings(viewModel);
},
error: function (data) {
alert("ERROR");
}
});
function toKoObserable(post) {
return {
P_Id: ko.observable(post.P_Id),
P_Title: ko.observable(post.P_Title),
P_Post: ko.observable(post.P_Post),
P_Comments: ko.observable(post.P_Comments),
P_IsDeleted: ko.observable(post.P_IsDeleted)
};
}
$("#saveAll").click(function () {
var saveData = ko.toJS(viewModel.posts);
$.each(saveData, function (index) {
var current = saveData[index];
var action = "PUT";
var stringyF = JSON.stringify(current);
var vUrl = "/api/Posts?P_Id=" + current.P_Id;
if (current.IsNew) {
action = "POST";
vUrl = "/api/Posts";
}
$.ajax(
{
url: vUrl,
contentType: "application/json;charset=utf-8",
type: action,
data: JSON.stringify(current)
});
});
});
});
Provide the reference of this file in the "Index.cshtml" file.
Step 5
Now write some HTML code and a reference of the Knockout file in the View "index.cshtml". This file exists in the "Home" folder.
Add the following code:
<div id="body">
<div class="left-section" style="height: 600px; width: 25%; float: left; background-color: #b9b9b9">
<h2>Posts</h2>
<button data-bind="click: newPost">New Post</button>
<button id="saveAll">Save</button>
<ul data-bind="foreach: posts">
<li style="list-style: none">
<a data-bind="text: P_Title, id: P_Id" href="#"></a>
<input type="button" value="Select" data-bind="click: $parent.selectPost" />
</li>
</ul>
</div>
<div class="right-section" style="height: 600px; width: 75%; float: left; background-color: #d9d9d9"
data-bind="with: selectedPost">
<div>
Post Title:
<input data-bind="value: P_Title" />
</div>
<div>
Post Number:
<textarea data-bind="value: P_Post" ></textarea>
</div>
</div>
</div>
@section Scripts{
<script src="~/Scripts/knockout-2.2.0.js"></script>
<script src="~/Scripts/ko-post.js"></script>
}
Step 6
Execute the application:
![Display Output]()
When we click on the select button it displays two TextBoxes, one for the title and the other displays the post number.
![Display Binding]()
When click on New Post button then it adds a new post:
![Add New Post]()