Kendo UI CRUD operations against WCF Data Services 5.1 OData in an MVC 4 project.

Introduction

This article received a major update on Dec. 12th, 2012 to account for OData v2 vs v3.

In a previous post, I covered selecting data from an ASP.NET WebAPI controller using OData. At the end of that article, I pointed toward possibly using WCF Data Services instead. This article will explore that option; doing the CRUD operations against WCF.

To demonstrate this, we are going to once again use the sample database from the Microsoft MVC Music Store project. We are going to use the Kendo Grid Widget to display a grid of all the albums in the music store, and provide the ability to edit them. Microsoft just released version 5.1.0 of the WCF Data Services and OData support, so we will also be using these new libraries.

I intend for this to be a long article, stepping through the entire process, starting with creating the project.

The completed, working source for this sample project can be downloaded from https://github.com/rally25rs/KendoWcfSample

MVC and WCF?

Sure. Why not? If you have heard anything from Scott Hanselman in the last couple years, you will have heard the phrase “One ASP.NET.” Basically, that all these Microsoft web technologies are all running off a common stack. A project doesn’t have to be just WebForms, or just MVC, or just WCF. They can all co reside and play nice together. Don’t believe the “new project” selection dialog box when it makes you choose between Web Forms or MVC or WCF or whatever else… all those templates are variations on the same core ASP.NET stack.

Creating the Project

We are going to start with a new MVC4 project. We still want some of the MVC functionality for serving up our web pages, so this is a good place to start. So fire up VisualStudio, and lets make a new project. Here I have chosen a MVC 4 Web Application project type, and named it “KendoWcfSample”.

We are then presented with a new dialog to choose a specific MVC template. Here I am choosing an “Internet Application,” primarily because it sets up Forms Authentication for me. We are going to use forms auth later to secure the “CUD” portions of our CRUD operations.

At this point, you should be able to build and run the app, and verify that it is working.

Adding the Database and Data Models

As I mentioned above, we are going to snag these from the Microsoft MVC Music Store project.

Start by browsing to http://mvcmusicstore.codeplex.com then choose the “Source Code” tab, and set the branch to “ASP.NET-MVC-4-Release” (I think the “master” branch is the original MVC3 version, not MVC4).

Through whatever means are easiest for you (probably either checkout the Music Store repo, or copy/paste from the browser), bring all the files from the “\Models” directory into your KendoWcfSample project in VisualStudio, except for AccountModels.cs, which was already created by the MVC template.

In each of these files, you should also correct the namespace. They are likely still “MvcMusicStore.Models”, so let’s rename them all to “KendoWcfSample.Models”:

Next we need to set up the DB connection string. In your Web.config file, add this to the <connectionStrings> element:

    <add name="MusicStoreEntities"
         connectionString="Data Source=(LocalDB)\v11.0;
             AttachDbFilename=|DataDirectory|\KendoWcfSample.mdf;
             Integrated Security=True"
     providerName="System.Data.SqlClient" />

This will use SQL Server Local DB, and a file named KendoWcfSample.mdf to hold our EntityFramework data.

Generate the Database and Sample Data on App Start

One of the files we copied in from MVC Music Store is SampleData.cs. If you look at that SampleData class, it extends DropCreateDatabaseAlways. This is an Entity Framework class that, when run, will drop and recreate the database, and run the Seed() method to load our test data.

What we need to do is register this class as our database initializer. Back in the MVC Music Store project, look at the file App_Start\AppConfig.cs. We will use this as an example for our own AppConfig.cs. This code does 2 things; first it calls:

    System.Data.Entity.Database.SetInitializer(new Models.SampleData());

This sets our SampleData class as the initializer for EntityFramework.
Then it also creates an “admin” user, so we have someone to log in as.

Here is our App_Start\AppConfig.cs:

using System.Web.Security;
using KendoWcfSample.Filters;
using WebMatrix.WebData;

namespace KendoWcfSample
{
    public static class AppConfig
    {
        public static void Configure()
        {
            System.Data.Entity.Database.SetInitializer(new Models.SampleData());

            CreateAdminUser();
        }

        private static void CreateAdminUser()
        {
            const string username = "Owner";
            const string password = "p@ssword123";
            const string role = "Administrator";

            new InitializeSimpleMembershipAttribute().OnActionExecuting(null);

            if (!WebSecurity.UserExists(username))
                WebSecurity.CreateUserAndAccount(username, password);

            if (!Roles.RoleExists(role))
                Roles.CreateRole(role);

            if (!Roles.IsUserInRole(username, role))
                Roles.AddUserToRole(username, role);
        }
    }
}

Now we just need to call AppConfig.Configure() when the app starts. To do this, open Global.asax.cs and add a call to AppConfig.Configure() in the Application_start() method:

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            AppConfig.Configure(); // <-- Added Here
        }
    }

At this point, the code should build and run. Run the app and let the initial page load in your web browser. Once it gets there, take a look in the \App_Data folder, and you should see our created database files:

You should also be able to log in to the app with username “Owner” and password “p@ssword123”.

Creating the WCF Data Service

Now that we have an MVC4 app and a database with test data set up, let’s add WCF Data Services. I like to put my services in their own directory, so let’s create a new folder named \Services:

Now add a new file to this folder, and choose WCF Data Service. I named it “MusicStore.svc” for this sample.

This gives us a generated service file that will look something like:

//------------------------------------------------------------------------------
// <copyright file="WebDataService.svc.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace KendoWcfSample.Services
{
    public class MusicStore : DataService< /* TODO: put your data source class name here */ >
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }
}

The first thing to do here is to put our data context class Models.MusicStoreEntities into the DataService<> generic. Then in the InitializeService() method, add an SetEntitySetAccessRule for each property in the data context that we want to make accessible. For this sample, I am just going to use Albums, Genres, and Artists, so I will add those 3.

So after some edits, the file Services\MusicStore.svc.cs contains:

using System.Data.Services;
using System.Data.Services.Common;
using KendoWcfSample.Models;

namespace KendoWcfSample.Services
{
    public class MusicStore : DataService<MusicStoreEntities>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("Albums", EntitySetRights.All);
            config.SetEntitySetAccessRule("Artists", EntitySetRights.AllRead);
            config.SetEntitySetAccessRule("Genres", EntitySetRights.AllRead);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }
}

Notice that our Albums and Genres are currently set to read-only, but Albums is set to EntitySetRights.All which will allow read-write access to everyone. We only want administrators to be able to update the albums, but anyone can read them. We make this happen by adding a ChangeInterceptor to our data service:

    public class MusicStore : DataService<MusicStoreEntities>
    {
        private const string ADMIN_ROLE = "Administrator";

        public static void InitializeService(DataServiceConfiguration config)
        {
            // (code omitted)
        }

        /// <summary>
        /// Only admin users can modify Albums.
        /// </summary>
        [ChangeInterceptor("Albums")]
        public void OnChangeAlbum(Album album, UpdateOperations operations)
        {
            if (!HttpContext.Current.Request.IsAuthenticated || !HttpContext.Current.User.IsInRole(ADMIN_ROLE))
                throw new DataServiceException(400, "Albums can only be modified by an administrator.");
        } 
    }

Modifying the MVC Routes for WCF

At this point, we should be able to get our Albums by navigating to the WCF service with the URL: /Services/MusicStore.svc/Albums:

Well, now we get an HTTP 404. This is because the MVC routing system is trying to handle this URL, and doesn’t know what to do with it. We can fix this by telling WCF to ignore all the requests to /Services/*.svc. Open the file App_Start\RouteConfig.cs and add the line:

    routes.IgnoreRoute("Services/{resource}.svc/{*pathInfo}");

This will fix our routing, and now browsing to the service in a web browser will work. It will probably behave strangely, at least it does in Chrome, and just saves the result to a downloaded file, instead of showing anything in the browser, but that is OK.

Update WCF Data Services

OK, now we have our base project all set up. Now we start getting into the good stuff. The “good stuff” comes with the latest WCF Data Service bits. At the time of this article, the “production” version of WCF DS that is included when we created the project is v5.0.0 but WCF has some great new OData support in the just-released v5.1.0. We are going to update to that latest version to get all the goodness.

Start by opening the NuGet Console:

I like to start by running the command Update-Packages with no arguments, which will update all installed packages in the project to their newest production versions, but if you just want to grab the lattest WCF Data Services, run the command: Update-Package Microsoft.Data.Services

Add Kendo UI

Now we can finally add Kendo UI to our project. I am just going to reference it of the CDN by adding a few lines to the Views\Shared\_Layout.cshtml file:

        <!-- Kendo UI Styles -->
        <link href="http://cdn.kendostatic.com/2012.3.1024/styles/kendo.common.min.css" rel="stylesheet" type="text/css" />
        <link href="http://cdn.kendostatic.com/2012.3.1024/styles/kendo.default.min.css" rel="stylesheet" type="text/css" />

        <!-- Kendo UI JavaScript -->
        <script src="http://cdn.kendostatic.com/2012.3.1024/js/kendo.web.min.js" type="text/javascript"></script>

The .css files should be included in the <head> tag, just before your own custom .css files. The .js file should be included right after jQuery, since Kendo depends on jQuery.

For more information on setting up Kendo UI, see: Kendo Docs: Getting Started.

Side-note; if you want to see what the latest version is without re-downloading Kendo, look at the Release Notes.

Setting up the Kendo UI Grid Widget

For this sample, I am just going to replace the default MVC view, so lets open Views\Home\Index.cshtml and just delete everything in the file. Now with an empty file, add the element that will become the grid:

<div id="grid"></div>

That is all the HTML we need to do. Let’s also add some JavaScript. Since we are using MVC, back in the _Layout file, there is a section defined for scripts that will add them to the bottom of the page. So we can import a JS file by adding this to the Index.cshtml:

@section scripts
{
    <script src="~/Scripts/gridSample.js"></script>
}

Then also make a new Scripts/gridSample.js file, which is where we will be doing most of our work. In the new gridAsmple.js file, lets create the grid widget by using a jQuery selector to get the div, and calling .kendoGrid().

(function ($) {
    $("#grid").kendoGrid();
})(jQuery)

If you run the project at this point, you should get something like this:

Setting up the DataSource

Next, let’s set up a Kendo DataSource to perform the operations against our WCF Data Service.

(function ($) {
    var gridDataSource = new kendo.data.DataSource({
    });

    $("#grid").kendoGrid({
        dataSource: gridDataSource
    });
})(jQuery)

Within our DataSource, we specify a transport property, and within that, define the URL to the WCF service for each of the 4 CRUD operations:

    var gridDataSource = new kendo.data.DataSource({
        type: "odata",
        serverFiltering: true,
        serverPaging: true,
        serverSorting: true,
        pageSize: 20,
        transport: {
            read: {
                url: "/Services/MusicStore.svc/Albums"
            },
            create: {
                url: "/Services/MusicStore.svc/Albums",
                type: "POST",
                dataType: "json"
            },
            update: {
                url: function (data) {
                    return "/Services/MusicStore.svc/Albums(" + data.AlbumId + ")";
                },
                type: "PUT",
                dataType: "json"
            },
            destroy: {
                url: function (data) {
                    return "/Services/MusicStore.svc/Albums(" + data.AlbumId + ")";
                },
                type: "DELETE",
                dataType: "json"
            }
        },
    });

The first thing we do is set type to “odata”, telling the DataSource that it should use OData style parameters to communicate with WCF.

Then we set serverFiltering, serverPaging, and serverSorting to true. WCF will handle these operations all server-side. Optionally, we could set them to false, and Kendo would perform the operations on the client, but that would require much more data to be sent back to the client.

By setting pageSize to 20, we limit the server to 20 Albums per page. This means that the server will only send back 20 items at a time, not all 246 Albums that are in the database.

For each of the CRUD operations, we then specify the URL and type for each of create, read, update, destroy. For WCF, they are app going to the same URL, just using the HTTP action to indicate what to do. The interesting thing to note here is that Kendo can take a string as the URL, or a function that returns the URL. For WCF Data Services, when we are acting on a single entity during an update or delete we need to add the entity ID to the end of the URL (for example /Services/MusicStore.svc/Albums(123) to act on the album with AlbumId=123). We can do this with a function.

Setting the OData Version

We also need to set two very important properties on the HTTP header:

        transport: {
            read: {
                ...,
                headers: {
                    DataServiceVersion: "2.0",
                    MaxDataServiceVersion: "2.0"
                },
            },
            create: {
                ...,
                headers: {
                    DataServiceVersion: "2.0",
                    MaxDataServiceVersion: "2.0"
                }
            },
            update: {
                ...,
                headers: {
                    DataServiceVersion: "2.0",
                    MaxDataServiceVersion: "2.0"
                }
            },
            destroy: {
                ...,
                headers: {
                    DataServiceVersion: "2.0",
                    MaxDataServiceVersion: "2.0"
                }
            }
        }

We set this on all 4 of the CRUD operations (technically ‘destroy’ does not need these headers defined because it passes no JSON, but I like to include it for consistency). These properties are defined in the OData specification and is used to tell the server what version of OData we are using. WCF 5.1 supports up to OData v3.0, however Kendo UI is built with the v2.0 specification. The format of the JSON messages changed between v2 and v3, so we can avoid a lot of headaches by simply telling WCF to use v2. Another way to do this would have been to set it in WCF itself with the line:

config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

However in my opinion it is better left to the client. This way if you share your web service with anyone else or ever make it public, others aren’t forced into OData v2.

Setting up the Grid

Now we can set up the basic properties of the grid. We are going to use an editing mode called “inline,” just because it is the one I like best. There are other edit modes that can be seen in the Kendo UI Grid Demos.

Here is our initial grid code:

    $("#grid").kendoGrid({
        editable: "inline",
        filterable: true,
        pageable: true,
        sortable: true,
        dataSource: gridDataSource,
        toolbar: ["create"],
        columns: [
            { field: "ArtistId" },
            { field: "GenreId" },
            { field: "Title" },
            { field: "Price" },
            { command: ["edit", "destroy"], title: "&nbsp;" }
        ]
    });

Here I have set editable: “inline” to specify which editing mode we want.

To enable sorting, paging, and filtering, we simply set filterable, pageable, sortable all to true. Note that these are the same 3 things we told the DataSource that the server should perform server-side.

We want a toolbar at the top of the grid with a “Create” button in it for making a new row, so we specify toolbar: [“create”].

And then we specify each of the columns that we want to display. For now, I just specify the field for each. The last column will hold “Edit” and “Delete” button for that row, and so just contains the command: […] array with the commands we want to appear there.

So if we run the project now, we get a grid with data! If you pop open the dev tools and check out the request to the server to get that data, you can see that it indeed only returns 20 results in the JSON data, however at the bottom of the grid, we can see the paging knows how many total records there are. This is thanks to WCF Data Services v5.1.0-rc2 supporting the $inlinecount OData parameter.

So at this point, Read operations are working, so let’s keep on improving this code…

Defining the Data Model

Right now, our Album data model is defined in C#. Kendo, being all JavaScript, really has no idea what an Album looks like. Yes, it can read data from the server and display it right now, but it isn’t really remembering what that data structure looks like. When we want to add a new row, the DataSource needs to know what that new record would look like. This means we need to make a data model in JS that matches our Album class in C#. This is done using the schema.model property of the DataSource:

    var albumModel = {
        id: "AlbumId",
        fields: {
            AlbumId: {
                editable: false,
                type: "number",
                defaultValue: 0
            },
            ArtistId: {
                type: "number",
                defaultValue: 1
            },
            GenreId: {
                type: "number",
                defaultValue: 1
            },
            Title: {
                type: "string",
                validation: {
                    required: true,
                    minlength: 2,
                    maxlength: 160
                }
            },
            Price: {
                type: "number",
                defaultValue: 9.99,
                validation: {
                    min: 0.01,
                    max: 100.00
                }
            },
            AlbumArtUrl: {
                type: "string",
                validation: {
                    maxlength: 1024
                }
            }
        }
    };

    var gridDataSource = new kendo.data.DataSource({
        ...
        schema: {
            model: albumModel,
            data: function(data) {
                return data.value;
            },
            total: function(data) {
                return data.count;
            }
        }
        ...
    });

So you can see we are also specifying some validation properties, such as required, min and max numeric value, and min and max string length.

Now, when we ask the Grid for a new row, it knows exactly what that row should look like, and what kind of editors it should use for each field.

At this point, ALMOST everything in the grid works (remember to log in first if you want to try to create, update or delete!). Play around with sorting and filtering and have a look at the requests and responses. You will see that it all happens on the server!

Getting the Names for Genre and Artist

The Genre and Artist columns are ugly, and just showing the numeric GenreId and ArtistId. Not exactly what we want. Instead, we can use a feature of the Kendo grid called a “foreign key column” to specify a list to look up the Genre and Artist names.

To specify a foreign key list, we need to get an array of objects that follow the format:

{
    value: 1,
	text: "Name"
}

where value is the ID (GenreId or ArtistId) and text is the name to display instead of the ID.

The catch is that we need to actually load the list, not just use a Kendo DataSource. We can do this by initially creating a Kendo DataSource, and immediately calling .fetch() on it. The fetch() method is run asynchronously, and can take a function as a parameter to be run when the fetch is complete. In this function, we use jQuery’s $.map() function to transform the genres returned to the { value, text } format expected by the Grid.

    var getGenresAsync = function () {
        var deferred = $.Deferred(),

            loadGenres = function () {
                new kendo.data.DataSource({
                    type: "odata",
                    serverPaging: false,
                    transport: {
                        read: "/Services/MusicStore.svc/Genres?$select=GenreId,Name"
                    },
                    schema: {
                        data: function (data) {
                            return data.value;
                        },
                        total: function (data) {
                            return data["odata.count"];
                        }
                    }
                }).fetch(function (data) {
                    deferred.resolve($.map(data.items, function (item) {
                        return {
                            value: item.GenreId,
                            text: item.Name
                        };
                    }));
                });
            };

        window.setTimeout(loadGenres, 1);
        return deferred.promise();
    };

A JSON deferred is returned here so that we know when the genre foreign keys are finished loading. We also use the OData $select parameter on the URL: “/Services/MusicStore.svc/Genres?$select=GenreId,Name” to indicate to WCF that we only want the GenreId and Name columns returned in the data. This helps cut down on the amount of data that needs to be transferred.

Once this deferred is resolved, we can load the grid.

    $.when(getGenresAsync()).done(function (genres) {
        $("#grid").kendoGrid({
		    ...
        });
    });

Now the genre names are displayed instead of the genre IDs, and when we edit the row, the Genre column gets a dropdown list of all the genres. The same can be done for the Artists.

Conclusion

I’m an old-school WCF fan, so call my biased, but WCF Data Services 5.1 has awesome OData support. It works very well with Kendo UI. WCF Data Services integrates well with ASP.NET MVC projects too. Next time you need to do full CRUD operations against an ASP.NET solution, or provide server-side sorting filtering and paging, consider using WCF Data Services and Kendo UI!

The completed, working source for this sample project can be downloaded from https://github.com/rally25rs/KendoWcfSample

Advertisements
Tagged with: , , ,
Posted in Programming
21 comments on “Kendo UI CRUD operations against WCF Data Services 5.1 OData in an MVC 4 project.
  1. valx says:

    Thanks. Impressive. Very clearly explained.

  2. looks promising, have to try it. and if it works maybe I should forget about Web Api?

  3. so I tried it works, but I have issues with batch editing. When I do an INSERT operation I get back a created row, but my grid would not refresh the new ID field. So if I update the newly created row, I would end up with a new row in the DB, because it will PUT an Id=0.

    How do I refresh the GRID after INSERT is done?

  4. your code works for one insert, but do 2 insert in a row and you’ll get

    0x800a138f – Microsoft JScript runtime error: Unable to get value of the property ‘AlbumId’: object is null or undefined

    • rally25rs says:

      Thank you for pointing out this problem. It turns out that when a record is being inserted, the server is replying with the updated record, but Kendo is having problems updating the new record with its ID. The new record then ends up still being flagged as “new”, so it keeps trying to insert it. I did a bunch of debugging to find out why this is happening and eventually found it (it is related to how my “schema.data” function is set up), but I have a question in to the Kendo team to see how to best handle it. As soon as I figure out a fix, I will update my code and let you know. Thanks again!

    • rally25rs says:

      I updated the post to fix this issue. Take a look at the new section titled “Getting the newly created ID back, and dealing with odata.metadata (Where things get tricky!)” and thanks again for pointing out the problem!

    • rally25rs says:

      I just made another major update to this post. I realized that I was putting in javascript to handle the WCF response formatting because it was returning v3 OData, but I could eliminate all that by setting the OData version to 2.0 int eh HTTP headers. You can eliminate a bunch of code in the DataSource schema.data, schema.total, and schema.parse. Check out the new section above titled “Setting the OData Version”.

  5. Today, there was a release from Microsoft : “New ASP.NET Web API functionality, including support for OData, integrated tracing, and automatically generating help page documentation for your API.”

    I now have dilemma, not sure whether to go with WCF or Web api? What do you think about it?

    • rally25rs says:

      I must have missed that announcement. I haven’t tried new WebAPI yet. Honestly, I would just take 2 or 3 days and try each one and see which causes less pain for your application architecture and features that you need.

  6. Oli Gray says:

    Great article thanks. We have an existing architecture which uses KendoUI components served up by standard asp.net web forms (ASPX pages) which bind to WCF Data Services and custom REST based WCF Services. I would like to migrate the ASPX pages to MVC which you have illustrated nicely here, but my question is around the validation which MVC provides at the service layer. It is my understanding that if you used ‘pure’ MVC with the KendoUI server wrappers you can encapsulate the objects & validation logic on the server side. However, by adding OData into the mix you lose this functionality and have to replicate the validation/model on the client side as you show in this article. Is this just the price to pay for having the flexibility of an OData solution (i.e. queryable URL’s which can be used by multiple platforms) rather than concentrating on a more (potentially) application specific implementation using MVC?

    I’d love to hear your thoughts!

    • rally25rs says:

      You should be able to implement server-side validations by adding code to check the data annotations on your model to the WCF ChangeInterceptor, which is where I am validating the user is logged in as an admin in this code. There is an example of manually checking the data annotations here: http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx but I have not tried it myself yet, so am not sure if this person’s code actually works or not.

      • Oli Gray says:

        I was thinking more about the use of DataAnnotations in MVC which auto-magically push data field validations (like regExp and max string length) up to the front end using the Kendo UI MVC Wrappers? Using OData means that you don’t get this functionality and instead have to also define these restrictions manually on the client side using the Kendo DataSource as I understand it ?

  7. Dhruvit says:

    my controller is as follow:
    public class StudentController : Controller
    {
    public ActionResult Students()
    {
    return View();
    }

    public JsonResult ListStudents()
    {
    var stud = new StudentDataContext();
    var model = (from st in stud.StudInfos
    join res in stud.Results on
    st.Id equals res.StudentId
    select new Student
    {
    Id = st.Id,
    Name = st.Name,
    City = st.City,
    Subject = res.Subject,

    Result = res.Result1
    }).ToList();

    return Json(model,JsonRequestBehavior.AllowGet);

    }
    }

    & in Student/Students.cshtml code is as shown below:

    $(document).ready(function () {
    $(“#grid”).kendoGrid({
    dataSource: {
    type: “odata”,
    transport: {
    read: “/Student/ListStudents”

    },
    schema: {
    model: {
    fields: {
    Id: { type: “number” },
    Name: { type: “string” },
    City: { type: “string” },
    Subject: { type: “string” },
    Subject: { type: “string” }
    }
    }
    },
    pageSize: 20,
    serverPaging: true,
    serverFiltering: true,
    serverSorting: true
    },
    height: 330,
    filterable: true,
    sortable: true,
    pageable: true,

    columns: [
    { field: “Id”, title: “Enrollment No.”, width: 140 },
    { field: “Name”, title: “Student’s Name”, width: 110 },
    { field: “City”, title: “City”, width: 110 },
    { field: “Subject”, width: 110 },
    { field: “Result”, title: “Result”, width: 90 }]
    });
    });

    but no any filtering/sorting are working,what is type=”odata”,i feel that there is fault of it & what is the possible values of type in datasource.

    Thanks to review my problem…

  8. Dhruvit says:

    how to highlight a raw by giving it background color.
    suppose i want to see the raw in yellow bgcolor where country=”india”
    thanks to review my problem

  9. kunal says:

    Great Article.
    Can you please let me know about following :
    Can we implement server side grouping using WCF Data Services (v3) on service side and Kedo Ui on Client Side. Please help.

  10. Isaac says:

    This is a wonderful article Jeff, thank you! I am working on a project that requires OData like you have demonstrated, but also needs to have client and server side validation. Do you have any resources on implementing something like this, whether it be the changeInteceptors you mentioned or something else?

    I’d appreciate any help, thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

CodingWithSpike is Jeff Valore. A professional software engineer, focused on JavaScript, Web Development, C# and the Microsoft stack. Jeff is currently a Software Engineer at Virtual Hold Technologies.


I am also a Pluralsight author. Check out my courses!

%d bloggers like this: