Main menu

Tag Archives: odata

Apologize for the delay, this article was actually published last month. If your a .NET developer specifically with ASP.NET (MVC, Web API/REST, Entity Framework, OData, etc.) and have heard or had interest in the MEAN stack, especially Node.JS, server side development in JavaScript – made possible with Google’s V8 open source JavaScript engine, have a quick read (and YES the entire MEAN stack will run in Azure just as your traditional .NET web stack would).

MSDN: Building Web Apps on the MEAN Stack with OData in Microsoft Azure

Update: 5/1/2014 – Customer View & customerController.js has been updated to toggle styles by manipulating the DOM through the ViewModel with ng-show to adhere and stay consistent with AngularJS best practices.

With AngularJS and ASP.NET MVC, we now have an MVC pattern and architecture for both on the client and server. What do we do and/or how do we approach this? Well one can argue we don’t use any of the MVC architecture on the server and build out a full-fledged AngularJS front-end application and only use make async calls to Web API for all things that absolutely need to be on the server e.g. CRUD, workflows, business logic, etc.

Now, there’s absolutely nothing wrong with this approach, and for the most part a lot of heavy front end SPA’s are built this way in ASP.NET MVC. However, with all the .NET, ASP.NET and AngularJS goodness, why not leverage the best of both worlds? Again, there’s absolutely nothing wrong with building a pure AngularJS application and only using Web API, but for this blog post we’ll go over patterns of using the best of both worlds along with integrating AngularJS with Kendo UI.

Note: for those that prefer to build a pure AngularJS front-end and only leveraging Web API on the backend (which many devs prefer), simply ignore the MVC Razor sections. If this is the case you can also opt to render raw *.html vs. *.cshtml views as well.

Let’s take a look at our Project structure for all things client-side.

Staying true to the AngularJS seed (sample) application from the AngularJS team, we’ll also create an “app” folder under “scripts”, staying true to ASP.NET MVC, where JS scripts are supposed to reside.

This is where our AngularJS application bootstrapping process takes place, here we’ve declared our new app “northwindApp” and we register all our routes (URL’s) for our SPA application. Note, if you’re not building a SPA, you can still leverage all the AngularJS goodness and architecture it brings (which btw, is huge), you can just omit the registering any of the routes in this step. Notice, the parameters we are passing into the module method: “northwindApp” is the name of our app, after that it’s an array of all the AngularJS modules we want injected into our application:

“kendo.directives” are needed so that we have full integration with AngularJS and Kendo UI, this will make more sense when we cover how AngularJS will compile Kendo UI widgets using directives.

“ngRoute” is needed so that we can configure our SPA routes, if your familiar with ASP.NET MVC routes, pretty much the same principles here, only difference here is routing of your application will take place on the client vs. the server. Here we are configuring each out with the “when” method by simply passing in the path in the URL and within the “when” we configure what the server URL path is to remotely load the View and which Controller to use. The “otherwise” method is simply a default route that will be used if none of the other routes are matched from what’s in the URL. You could route the default “otherwise” route to go to a custom 404 page, for our purposes we’ll just route the user to the default home page.

“ngAnimate” is injected here so that we can add some animation when AngularJS swaps out our Views in our SPA.

AngularJS has the notion of scopes with in application, there is one $rootScope and multiple children $scopes (so to speak), in your application. The best .NET analogy of a scope is something like a context, so $rootScope would map to an ApplicationContext (global with Singleton like behaivor) and $scope would map to something like a (if we had one) ControlllerContext. $scope is more of a context that you use to as an adhesive to bind you View to your Controller. So from homeController.js you see that we’ve defined a property named “title” with the value “ASP.NET”, let’s take a look at our partial Home.cshtml mark-up.

Northwind.Web/Views/Home/Home.cshtml

<div class="jumbotron">
<h1>{{title}</h1>
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS, and JavaScript.</p>
<p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.
</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301870">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301871">Learn more &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="http://go.microsoft.com/fwlink/?LinkId=301872">Learn more &raquo;</a></p>
</div>
</div>

Notice the {{title}} on line 2, between the h1 tags, when the View (Home.cshtml) loads, AngularJS will replace the h1 html with the $scope.title value: “ASP.NET”.

Now that we have a primer to AngularJS’s MVVM pattern, let’s take a look at some bit more complex, the customerController.js which will display a Kendo UI Grid with the customizations which include a toolbar with buttons all wired up with Angular Kendo directives and AngularJS MVVM.

We declare a Controller by using the “controller” method, the first parameter is the name of our Controller, the second parameter takes a function who’s parameters are all the modules we want our Controller to be injected with. Our Controller is being injected with the following.

$scope, which we already know about

$rootScope, so that we can store some things to help us manage our View state, in this case we will store what was the last selected row on our Grid so that when the user navigates back to this view we can re-select the same row and highlight it.

$location, so that we can navigate from this View to other Views e.g. customer edit view which will have a form so we can make changes to a Customer.

customerDataSource, which is a reusable AngularJS service which returns a Kendo UI DataSource.

Notice how we are leveraging MVVM to manipulate the DOM to toggle the tool bar above the grid with the “ng-show” directive vs. manipulating the DOM with jQuery, this is key with AngularJS design principles.

We create the customerDataSource as a reusable AngularJS service using the “factory” method. The first parameter is the name of our service and the second parameter is method who’s parameters indicates that we are injected with customModel.

Here we can see that we that the declarative syntax for Kendo UI widgets have changed a bit, and at a first glance it seems that it’s dramatic change, but as they say, there’s a method to the madness. If you understand the convention here, it’s pretty simple, take look at the cheat sheet we have below for our view.

Customer.cshtml Cheat Sheet

Before (with Kendo UI)

After (with Angular Kendo)

data-role=”grid”

kendo-grid

data-sortable

k-sortable

data-bind=”source: dataSource”

k-data-source=”dataSource”

data-bind=”events: { change: onChange }”

k-on-change=”onChange(kendoEvent)”

For declarative widgets, we simply prefix with “kendo-“, quick note, where the name has camel casing, you would simply separate it with dashes e.g. DropDownList -> k-drop-down-list.

Options for a widget are simply prefixed with a “k-“.

For all things that were bound with “data-bind”, simply become first class citizen attributes again following the dash-separted convention.

Same for events, however the only other item, is that you have to explicitly pass in a “kendoEvent” vs. before you didn’t.

If we run our application, we can see that everything renders and it’s business as usual.

For the customerEditController.js, we are being injected with $scope, $routeParams, $location and customerDataSource, notice the reusability of our customerDataSource. We use the customerDataSource to hydrate our grid with a list of customers on our Northwind.Web.Views/Conrollers/Index.cshml view as well as our Northwind.Web/Views/Customers/Edit.cshtml view with a single customer.

On the Sever-Side of Things

In the beginning of the post, we mentioned leveraging the best of both worlds, we’ve seen how we done this on the client side of things with all the goodness of AngularJS and Kendo UI. AngularJS brings a nice fully fledged framework which forces us to using nice well defined patterns (MVC’ish & MVVM), which has a natural side effect of having an elegant architecture on the client side. So how do we make the most of ASP.NET MVC on the server side? Simple, we follow all the best practices as we’ve always been doing in the past.

Notice how we have very little mark-up here and this View is simply for us to server up all the HTML in our Northwind.Web/Views/Shared/_Layout.cshml, then the @RenderBody() will render Northwind.Web/Views/Home/Index.cshml which will have the “div” element where AngularJS will load our AngularJS Views into on the client side.

In CustomerController.cs, we are returning PartialView’s vs. View’s, well because that’s what they really are now “PartialViews”, there simply chunks of HTML that AngularJS will remotely load into our div> element when swapping views.

This is fairly straight forward, and we used the Visual Studio 2013 Update 2 RC out of the box Controller scaffolding to generate most of this code. We then replaced the code that was directly using Entity Framework to use a Repository and Service pattern, for more information on the pattern used please have a quick read here: https://genericunitofworkandrepositories.codeplex.com.

We’ve added some rudimentary animation with .ng-enter and .ng-leave, both which the cubic-brezier, to slide in our Views. This implementation was originally based off AngularJS original animation documentation for “ng-view”, please have a quick read up here: https://docs.angularjs.org/api/ngRoute/directive/ngView for more details.

There you have it AngularJS, Kendo UI with Angular Kendo and ASP.NET MVC 5, all harmoniously with the best of both worlds.

Apologize for the delay, the original article: “Harness the Power of ASP.NET MVC, Web Api, OData, Kendo UI & RequireJS to Build an Easy & Maintainable SPA (for the .NET Developer)” has now been published as “A .NET Developer Primer to Single-Page Applications (SPA)“.

Just a quick recap on the last post, we wired up the Kendo UI Grid, DataSource with MVVM with all the traditional CRUD functionality. In this blog we’ll cover editing with a form in a Kendo UI View that is remotely loaded into our SPA that is bound the Kendo UI Datasource using MVVM. The View will be loaded in from with a click of a button on the row your are trying to edit from the Kendo UI Grid.

Our Web Api OData ProductsController, pretty much the same Controller used in the previous blog to hydrate our Grid along with the other CRUD actions. This Controller will also share the same duties as it did before, for the Grid. Here it handle hydrating the Form, perform updates and deletes.

The onChange (delegate) event handler will be responsible for saving off the last selected rows ProductID so that if we navigate to the ProductEdit View and back we can maintain the last selected row state.

Creating the ProductEdit View

Spa/Content/Views/productEdit.html
(styles have been omitted, for clarity)

The ProductEdit View will be bound to the Kendo Observable Model that the Datasource will return. It’s called Observable Model because the there is two-binding between the Form and the Model, meaning when a change happens in the Form, it is automatically synced with the Model, which is bound to the Datasource.

You can essentially setup auto-sync on the Datasource so that when there are changes, it will automatically sync back to our OData Web API ProductsController. However for purposes of this post we will stick to a manual sync when we are ready to send our updates to our Controller.

Notice how everything that needs to bound is using the attributes prefixed with “data-“. This is what the Kendo Web MVVM Framework will scan for when when binding a View with a Model, long story short, this is how you specify the binding mapping options for the following:

The Product Datasource is responsible for loading the Product details and providing a Observable Model the Form can bind to. It will handle all the rest of the CRUD activities such as updating and deleting the Product. All of the CRUD activities handled by the Datasource will happen over REST using the OData protocol asynchronously.

This is how we set up our Observable Product Model that will be returned from the Datasource and bound to the View. We can see here we define the primary key field (property), fields, and methods that are View buttons will bind to. When the saveProduct method is invoked, we will perform a sync, meaning all changes in the dataSource will be sent back to the server side for processing when this is invoked. Because our Model is an Observable Model, and there is two-way binding between the Model and the Datasource (as mentioned earlier), the Datasource is keeping track and knows of all the changes that are happening.

Notice how the cancel method is a redirect with the hash (#) in it, so when the redirect happens the Kendo Router will process this and have our SPA load in the Products View which is the Grid with the Product listing.

The parameterMap purpose is so that we can intercept and perform any pre-processing on the payload before it is sent to our Controller.

We are deleting all the properties that are not needed by our Controller, more importantly, we are doing this so that we don’t have any extra properties that are not on our Product Model or Entity, so that the MVC ModelBinder will recognize our payload and bind it to the Product parameter on our UpdateEntity(int key, Product update) method on our ProductController.

We are also converting the UnitPrice to a string before we sending back to the server side, because the UnitPrice type is decimal, and currently when using Web Api and OData, the MVC out of the box ModelBinder is not smart enough (yet) to convert a number to decimal in the ModelBinding process. Ironically, it is smart enough to convert to decimal if we send it as a string, so that’s what we’ll send of for now.

Here we are simply transforming the payload before binding it to the Form, we are removing the data.odata.metadata property since it’s really not needed and unpacking the data.

total

total: function (data) {
return 1;
}

The total defined method here is simply returning the count of how many records where returned from the server, we are always returning 1 here, since this is a form bound to a single Product at all times. You can add some null checking here to return 0 or 1.

This will invoke the Datasource to make a call to our Controller Get() method, and load the Product, notice how we are passing in a callback so that when the loading is complete (because it’s happening asynchronously) we are then setting to the variable productEditModel because this is the convention we need to follow mentioned in the previous posts (e.g. view, viewModel, view.html). Because we are following these conventions, our implantation in the Index.html view will work off of these conventions and bind the View to the correct Model for us.

There you have it, MVC 4, Web API, OData, EF, Kendo UI, Binding a Form to Datasource (CRUD) with MVVM – Part 3.

Let’s get Web API setup and configured with OData, you will need the Nuget package Microsoft ASP.NET Web API OData.

We will use a SQL Server Compact (4.0) Northwind database for this example, you can easily use a full SQL Server Database if you’d like with libraries in this project. I’ve tested them both and they work fine. Both the Northwind SQL Compact and SQL Server database are included in the sample download application that will be available for download in Part 3 of this series. For all of those who are wondering, why did I use (embedded) SQL Server Compact for as web app..?! Well, because I can host the SQL Server Compact database in my Windows Azure Website for free..!

You will need the NuGet package EntityFramework.SqlServerCompact and Microsoft.SqlServerCompact packages. You can read up on some more in-depth details on how to setup ASP.NET MVC with SQL Server Compact Databases here.

We need to create a ProductController so that we can provide data to our View, this controller will inherit the EntitySetController which inherits the ApiController that we all know so well, so we can serve up our data using OData.

The response body contains the OData service document in JSON format. The service document contains an array of JSON objects that represent the entity sets. In this case, there is a single entity set, “Product”. To query this set, send a GET request to http://localhost:port/odata/Products. The
response should be similar to the following:

One of the important take aways here, is by implementing OData with a data provider (e.g. Entity Framework) that supports IQueryable all of our REST HTTP GET queries options (e.g. skip, take, sort, filter, equals, etc.) are automatically translated for to us to Entity Framework, so that we don’t have to wire up any of this.

Let’s launch Fiddler again and see this in action and do a OData HTTP GET request querying for product that has the name equal to “Chai”.

Again, querying is navtively supported out of the box with OData and a data provider that supports IQueryable, however if we re-visit our ProductController, we didn’t have to write up any code for this..!

Notice how there is very little, if any, of our own code here. All we’ve done, is simply configured (filling in the blanks) the Kendo Datasource.

The important items to note here is that by default our OData enabled ProductController returns the count as data.odata.count and our data set in data.value, with this being the case we will need to help the Datasource by unpacking this and returning it to the Datasource. You can see how this is done in the schema data and total functions defined above.

We also define the model in the Datasource, the model inherits Kendo’s Observable object (class), meaning their is two-way binding with the Grid and Datasource, so anytime something happens on the Grid updates are automatically sent to the Datasource, then sent to our ProductsController.

The productGrid is declaratively attributed using the data- attributes, this is what Kendo UI MVVM uses for binding the View to the Model.

Here we are simply subscribing to viewSwitchedEvent that is published from the host page (Spa\index.html) of our SPA. This event is published (raised) everytime is View switching is complete. Here we check that the View that was switched in place was indeed the products View and that it was the first time is was loaded remotely from the server, if so, we bind the View to the Model. We do this only on the first time it loads from the server because there is really no need to do this more than once.

Now let’s load up the application and see our Products listing.

Testing Filtering and Sorting

Testing Inline Grid Editing

Testing Inline Grid Deleting

We see this error:

An error has occurred.

The primary key value cannot be deleted because references to this key still exist. [ Foreign key constraint name = Order Details_FK00 ]

Which is expected since the Order Details still has foreign keys to the Product table.

There you have it MVC 4, Web API, OData, Kendo UI, Grid, Datasource with MVVM. To spice things up, I changed the Kendo UI CSS to the Metro UI theme.