Connect KendoUI to MVC Web API without ODataController

This is in response to a recent post by Steve Smith (Connect KendoUI AutoComplete to MVC Action).

In his post, Steve stated that using Web API to connect a KendoUI AutoComplete with OData “can present a challenge”.

Yes, ODataControllers definitely present a challenge.. and, I admit.. the first time I tried to get KendoUI to talk to MVC without using an ODataController, I kinda wanted to pull all of my hair out.

But now that I’ve done it a couple dozen times, it’s not so bad.

I’ll walk you through the process now… 

Steve’s technique works for his example, but the technique below allows you to take full advantage of KendoUI’s controls. Later in the post, I’ll show you how this technique even works for the KendoUI Grid.

Step 1: Create a new MVC project if you don’t already have one:

Step 2: Make sure you select MVC and add Web API support:

Step 3: For this example, I want to show everything working with the latest stable bits.. So go to the Package Manager Console and run update-package . This will ensure that everything is up to date.

Step 4: There are a few nuget packages we need to install to make this work. Run these commands in the Package Manager Console

  • Install-Package KendoUIWeb  – Only do this if you don’t already have KendoUI installed. Also note that I’m using an older, discontinued version of KendoUI… For this example, that’s just the easiest thing to do.. this will definitely work on a newer version of KendoUI.
  • Install-Package Microsoft.AspNet.WebApi.OData  – While we’re not going to be creating ODataControllers in this example, we are going to be using some functionality from this nuget package

Step 5: Create a Web API controller to return data back to the KendoUI AutoComplete control:

using System.Linq;
using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Extensions;
using System.Web.Http.OData.Query;
using WebApplication9.Models;

namespace WebApplication9.Controllers
	public class KendoUiSampleController : ApiController
		private readonly ApplicationDbContext _context = new ApplicationDbContext();

		public PageResult<Order> GetOrders(ODataQueryOptions<Order> options)
			var settings = new ODataQuerySettings();

			var fromDatabase = _context.Orders.Where(order => order.Freight != 123);

			var results = options.ApplyTo(fromDatabase.AsQueryable(), settings);

			return new PageResult<Order>(
				results as IQueryable<Order>,

If that looks confusing, just know that line #18 is the most important line.. that’s where you specify what table you want the KendoUI control to search. In this particular example, I’ve also shown that you can perform additional filtering on the results (.Where(order => order.Freight != 123) ).

*OdataController officially avoided*

Beyond that, the code above is essentially taking the fancy OData URL that KendoUI generates (as options ), converts it to a LINQ expression, applies it to your database query, and formats the results into something OData-ish.

Step 5: Open /views/home/index.cshtml and replace all of the contents with:

    ViewBag.Title = "Home Page";

<input id="products" />
<div>Hint: type "che"</div>

@section scripts
    <link href="~/Content/kendo/2014.1.318/kendo.common.min.css" rel="stylesheet" />
    <link href="~/Content/kendo/2014.1.318/kendo.default.min.css" rel="stylesheet" />
    <script src="~/Scripts/kendo/2014.1.318/kendo.web.min.js"></script>

        $(document).ready(function () {
                dataTextField: "ShipName",
                filter: "contains",
                minLength: 3,
                dataSource: {
                    type: "odata",
                    serverFiltering: true,
                    transport: {
                        read: {
                            url: "/Api/KendoUiSample/GetOrders",
                            dataType: "json"
                    schema: {
                        total: "Count",
                        data: function (response) {
                            return response.Items;


That’s essentially the exact same sample code you’d find at this KendoUI AutoComplete example.

Lines 34-35 are the biggest changes to the original KendoUI sample.  That’s simply required to make KendoUI understand the data that Web API returns.

And that’s it. It works exactly the same as the original KendoUI example.

For the sake of fun, I added a KendoUI Grid to my example and uploaded the whole thing to github here.

The downside to this technique is that it’s read-only. The KendoUI Grid, for example, does have functionality to allow creating, updating, and deleting rows, but you’ll have to go with the full-blown ODataController if you want that kind of functionality.

Hope this helps someone..