Main menu

Our team has been heads down working with VSCode, TypeScript, AngularJS, Kendo UI and last but not least NativeScript. VSCode has quickly become our teams de facto IDE and TypeScript has become the standard when it comes to any JS development. TypeScript has definitely helped us with large scale enterprise JS development. I’ve recently published an article on Telerik Developer Network: “Improving Development with TypeScript“, which dives into why TypeScript is an absolute must. If VSCode and/or TypeScript sparks any interest (which it should), have a quick read 🙂

Note: source link can be found in the published article, back-end source code is NodeJS, however it could easily be be hosted on any other back end server e.g. .NET, Java, etc. since it’s really just an AngularJS front end app.

Like this:

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

Customer Profile
CB Richard Ellis (CBRE) is one of the world’s premier full-service real estate companies, with 349 offices in 42 countries and over 44,000 employees. The company’s $223 billion in transactions span sales and leasing, loan originations, property and corporate facilities management and much more, making CBRE the global leader in real estate services and investment.

Business Situation
CBRE has over 100 mobile apps–some public facing–but most are unique to the company internal operations. However, disparate development platforms scattered around the world made it difficult to maximize economies of scale. The company needed a framework to deliver application portability to a spectrum of devices and operating systems, while at the same time, providing the “wow” factor field agents needed to close real estate deals.

Solution
When CBRE application development shifted increasingly to HTML5 and CSS3, the development team conducted a thorough review of the competitive landscape and after an exhaustive research they chose the Telerik Kendo UI® framework.

Benefits

Less resources needed to develop, test and keep things consistent for a wide array of machines, browsers and versions

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.

This post is for those of us that are (primarily .NET developers) that have been accustomed to using Team Foundation Server as a source coded repository and now just getting started with Git. Git is a fairly mature and an advanced source code repository with many more features than I’ll actually get into. The intent of this screen cast is to get you started with Visual Studio 2013 Git integration. Although this screen cast uses CodePlex in the demo, the process should be the same for any another Git repository e.g. TFS 2012+, GitHub.com, CodePlex, Visual Studio Online TFS, etc.

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)“.

Update: 02/24/2014 – v3.2 released, improved API and reusable queries with the Object Query Pattern. Breaking change: Framework now ships returning all things TEntity or IEnumberable for compartmentalization, you will need to change the Repository.cs (see below, what methods signatures to change) if IQueryable is preferred over IEnumerable, IEnumerable is preferred as a best practice (http://genericunitofworkandrepositories.codeplex.com/documentation).

Update: 01/06/2014 – When viewing please configure your YouTube
player to 1080p for clear viewing of the coded demos.

Hope everyone had a wonderful New Years holiday, with the new year starting wanted to fulfill a high request, which was a quick start video on the Unit of Work and Repository Frameworks in ASP.NET MVC with Unity for IoC and DI.

1. Although the quick start video, takes the approach of committing the unit of work outside the ICustomerService exampled, whether you choose to do this inside your services or manage this outside, there is no right or wrong, this is totally team preference.

2. Also all use cases demonstrated in the CustomerController could have been satisfied by using the UnitOfWork out of the box without the need to implement the ICustomerService, however as mentioned, this is the preferred best practice.

In this case it is preferred that the IRepository return IEnumerable vs. IQueryable.

HAVING THE REPOSITORY RETURN ALL THINGS IEnumerable or IList is a best practice and preferred approach. Down the line, if you were to ever switch out your back-end, you won’t be bound to the requirements that the back-end implements IQueryable e.g. moving from EF to pure REST services.

Question? Why does the Repository in the framework return IQueryable?

Answer: Because most devs have been spoiled with ORM’s (e.g. nHibernate.Linq, Linq to Sql, Entity Framework) returning IQueryable and I received to many requests and complaints when the Repository layer in the Framework was returning IEnumerable or IList. Another caveat is that you can’t definitively tell what SQL queries are happening in your application by looking at the Repository layer, because you haven’t truly compartmentalized them in this layer; developers are more than able to modify the query plan before the query is actually executed.

For teams that prefer all things returned as IEnumerable from Repository layer, this would require three lines of code to be changed in the framework, here’s how: