jones.busy

technical musings of a caffeine converter

NAVIGATION - SEARCH

Extending Angular $http service

Recently, I’ve been working with AngularJs, developing an Azure targeted application with an Entity Framework (Code First) backend, Web Api v2.0 middle tier and an AngularJs front-end. I like AngularJS for a number of reasons, one of which is that, as a .Net, WPF developer for most of my time, having so many different options and approaches to consider with client-side web development, having a framework that minimises those options into one core approach is beneficial to me. I completely understand that this same reason could be seen as a negative and I am well aware of the impending re-write of Angular due this year but to move from the safety net of a strongly typed .net background to the javascript playground, AngularJS feels a little like I’ve got some stabilisers on my dev bike Smile

Using the $http service over the weekend, I stumbled across a couple of issues:

1. Calling a web api method with a simple string parameter:

public async Task<IHttpActionResult> PostRole([FromBody]string roleName)

The issue is that by sending the string across as a variable causes some misinterpretation of as it as a json literal so instead of the value finding its way to the web api method, you get a null object instead. So, instead of calling the following:

return $http.post(serviceBase + 'api/admin/roles', roleName);

You need to do this:

return $http.post(serviceBase + 'api/admin/roles', "'" + roleName + "'");

2. Calling a ‘get’ method from within IE:

public async Task<IHttpActionResult> Get()

For some unknown reason, no matter how hard I tried to stop this from caching when testing in IE, I had no luck. In the end, the only approach that worked for me was to randomise the request as follows:

return $http.get(serviceBase + 'api/admin/roles?rnd=' + new Date().getTime());

It’s not very pretty is it? Firstly, I must asking anyone reading that has any suggestions or comments about what I’ve done or the issues I have faced, please do get in touch as it is perfectly feasible I have completely crossed my wires with this and there is another approach I should have taken. But for now, these are the issues I hit, Googled, and then put in some workarounds.

Now, having found a workaround, I realised that these sorts of calls could be a regular occurrence and so I don’t want to have to remember to apply these fixes each time. My first thought was to see whether I could extend the $http service to wrap this functionality in a neat bundle for me. Coming from C# extension methods i looked at the following options:

1. prototyping

2. behaviours

3. providers

I’ve heard about most of these approaches but never seen any in practice. I really wanted to stick to passing in $http and just being able to either handle or extend the functionality to handle these requirements but could not get this to work with my limited javascript knowledge. In the end, I create a new service, extendedHttpService, which is actually a factory class that returns an extended version of the $http service:

(function (ng, app) { "use strict"; app.factory('extendedHttpService', ['$http', function($http) { var forceGet = function(url) { return $http.get(url + "?rnd=" + new Date().getTime()); }; var postString = function(url, str) { return $http.post(url, "\"" + str + "\""); }; $http['forceGet'] = forceGet; $http['postString'] = postString; return $http; } ]); })(angular, app);

Allowing me to then call the extended functions as follows:

(function (ng, app) { "use strict"; app.service('rolesService', ['extendedHttpService', 'appSettings', function (extendedHttpService, appSettings) { var serviceBase = appSettings.apiServiceBaseUri; this.getAllRoles = function () { return extendedHttpService.forceGet(serviceBase + "api/admin/roles/"); }; this.createRole = function (roleName) { return extendedHttpService.postString(serviceBase + 'api/admin/roles', roleName); }; this.updateRole = function (role) { return extendedHttpService.put(serviceBase + 'api/admin/roles', role); }; }]); })(angular, app);

This is much neater, but I’d love to hear on other approaches that I could have used in this scenario.

Separating Knockout Viewmodel from View

As mentioned in a previous post, I’m becoming a big fan of Knockout. I don’t favour MVVM over MVC per se, simply like the idea of being able to manipulate, and react to the model changing on the client side without the need for a return server trip every time.

Whilst it is perfectly normal for a Knockout view model to be declared inside the cshtml View to which it is bound, I have found that very quickly, the script can become quite bulky and difficult to maintain.

Take for instance the following script inside a View of mine:

   1: @section Scripts

   2: {

   3:     <script type="text/javascript">

   4:         /// <reference path="../jquery-1.9.1.js" />

   5:         /// <reference path="../knockout-2.2.1.js" />

   6:         /// <reference path="knockout.extensions.js" />

   7:         /// <reference path="../knockout.mapping-latest.js" />

   8:         /// <reference path="../jquery-ui-1.10.2.js" />

   9:         (function () {

  10:  

  11:             var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));

  12:             viewModel.currentView = ko.observable('company');

  13:             viewModel.editMode = ko.observable(false);

  14:             viewModel.editMode.subscribe(detailsRendering.toggleModelEdit);

  15:  

  16:             var btnActiveClass = 'btn-success';

  17:  

  18:             var manageSelection = function () {

  19:                 removeSelection();

  20:                 viewModel.currentView($(this).data("view-id"));

  21:                 addSelection($(this));

  22:             };

  23:  

  24:             var addSelection = function (element) {

  25:                 element.addClass("btn-primary");

  26:             };

  27:  

  28:             var removeSelection = function () {

  29:                 $(".detailsSelector").removeClass("btn-primary");                

  30:             };

  31:  

  32:             var toggleModelEdit = function (edit) {

  33:                 if (edit) {

  34:                     $("#lockModelBtn").removeClass(btnActiveClass);

  35:                     $("#unlockModelBtn").addClass(btnActiveClass);

  36:                 } else {

  37:                     $("#unlockModelBtn").removeClass(btnActiveClass);

  38:                     $("#lockModelBtn").addClass(btnActiveClass); 

  39:                 }

  40:             };

  41:  

  42:             $(".detailsSelector").on('click', manageSelection);

  43:             $("#lockModelBtn").on('click', function () { viewModel.editMode(false); });

  44:             $("#unlockModelBtn").on('click', function () { viewModel.editMode(true); });

  45:  

  46:             addSelection($("#companyDetailsSelector"));            

  47:  

  48:             toggleModelEdit(false);

  49:  

  50:             ko.applyBindings(viewModel);

  51:         })();

  52:     </script>   

  53: } 

It’s not very complicated but already I am finding it a little fiddly to follow. And, I’m not yet finished with the code, so it’ll only get bigger. I could separate out the areas responsible for initialising the view model from those responsible for reacting to user interaction with multiple script tags but a) that would add extra js code and b) I have a lot of overlap between the two areas of responsibility so scope is an important issue.

What I opted to go with is the Revealing Module Pattern (RMP) that provides a nice separation of concern in simplistic fashion. I created three RMP functions:

1. Initialise View Model

2. Initialise View

3. Handle User Interaction with the View

The resulting script is as follows:

   1: /// <reference path="../jquery-1.9.1.js" />

   2: /// <reference path="../knockout-2.2.1.js" />

   3: /// <reference path="knockout.extensions.js" />

   4: /// <reference path="../knockout.mapping-latest.js" />

   5: /// <reference path="../jquery-ui-1.10.2.js" />

   6: var details = function () {

   7:     

   8:     var initialiseViewModel = function (data) {

   9:         var viewModel = data;

  10:         viewModel.currentView = ko.observable('company');

  11:         viewModel.editMode = ko.observable(false);

  12:         viewModel.editMode.subscribe(detailsRendering.toggleModelEdit);

  13:  

  14:         ko.applyBindings(viewModel);

  15:  

  16:         return viewModel;

  17:     }

  18:  

  19:     return {

  20:         initialiseViewModel: initialiseViewModel

  21:     };

  22: }();

  23:  

  24: var detailsView = function () {

  25:  

  26:     wireEvents = function (vm) {

  27:         $(".detailsSelector").on('click', function () { detailsRendering.manageSelection(vm, $(this)); });

  28:         $("#lockModelBtn").on('click', function () { vm.editMode(false); });

  29:         $("#unlockModelBtn").on('click', function () { vm.editMode(true); });

  30:     },

  31:  

  32:     initialiseView = function (vm) {

  33:  

  34:         wireEvents(vm);

  35:         detailsRendering.manageSelection(vm, $("#companyDetailsSelector"));

  36:         detailsRendering.toggleModelEdit(false);

  37:     }

  38:  

  39:     return {

  40:         initialiseView: initialiseView

  41:     };

  42: }();

  43:  

  44: var detailsRendering = function () {

  45:  

  46:     var btnActiveClass = 'btn-success',

  47:     btnPrimaryClass = 'btn-primary',

  48:  

  49:     addSelection = function (element) {

  50:         element.addClass(btnPrimaryClass);

  51:     },

  52:  

  53:     removeSelection = function () {

  54:         $(".detailsSelector").removeClass(btnPrimaryClass);

  55:     }

  56:  

  57:     toggleModelEdit = function (edit) {

  58:         if (edit) {

  59:             $("#lockModelBtn").removeClass(btnActiveClass);

  60:             $("#unlockModelBtn").addClass(btnActiveClass);

  61:         } else {

  62:             $("#unlockModelBtn").removeClass(btnActiveClass);

  63:             $("#lockModelBtn").addClass(btnActiveClass);

  64:         }

  65:     },

  66:     manageSelection = function (viewModel, element) {

  67:          removeSelection();

  68:          viewModel.currentView(element.data("view-id"));

  69:          addSelection(element);

  70:      }

  71:  

  72:     return {        

  73:         toggleModelEdit: toggleModelEdit,

  74:         manageSelection: manageSelection

  75:     };

  76: }();

The first module, “details” (named after the view), providers a function for setting up the view model and returning. It does nothing else and knows of nothing else. The only dependency it has is on the initial input of the model which has come from the server.

The second module, “detailsView”, expects the view model and sets up the components in view from wiring the click events, to setting up the default view by calling into the third module, “detailsRendering”, which again expects the view model as an input and provides the functionality for manipulating the view based on either the user’s input or manually in the case of the detailsView initial setup. These three modules are in the same js file, but could quite easily be separated out, in which case, I’d be wise to use something like require to handle dependencies and also minimise the load.

To get the ball rolling, the html embedded script now looks like this:

   1: @section Scripts

   2: {

   3:     <script src="~/scripts/app/page.details.js"></script>   

   4:     

   5:     <script type="text/javascript">

   6:         (function () {

   7:             var viewModel = details.initialiseViewModel(ko.mapping.fromJS(@Html.Raw(Json.Encode(Model))));

   8:             detailsView.initialiseView(viewModel);

   9:         })();

  10:     </script>    

  11: }

Rather than returning the view model from the initial function, I could have called the initialiseView method from within but this way, I have the option of making further calls if needs be without the need to chain. Having spent most of my time in C# and Xaml, I’d love to hear from html and javascript guys on what their preferred approach to client side MVVM is.

Best Approach? EF5, Design Patterns, MVC and Knockout

One of the things I particularly like about Silverlight is that its rich client side model enables easy manipulation of data in a decoupled, data-bound fashion without the need to perform projection and/ or switching between to two different languages such as C# and JavaScript. What I don’t enjoy is the fact that in any distributed system that involves Silverlight, you will have to use some sort of asynchronous data-grab architecture so any lazy-loading or change tracking that may have been available on the server side gets lost. When working with MVC however, I find that even though I may have the full capabilities of EF at my disposal within the controller, the likelihood that I will push the same EF domain model classes into my view and few and far between. The main reasons:

1. Views usually only require a subset of the data so I don’t want to bulk up the response with more than I need.

2. JSON serialisation does not handle proxy version of classes designed to handle change tracking.

With point 2, you may come across this if you use Web API controllers and hit the error,

The type System.Data.Entity.DynamicProxies.SomeClass_SomeGUID was not expected…

The reason why point 2 is so important for me is because, coming back to Asp.Net from Silverlight, the desire to mimimise not just the amount of return trips to the server but to minimise the amount of data sent as well is too strong to ignore. With SL, the view is already on the client and all that happens is the data that is required is asked for and given. With vanilla MVC, you can make a request that returns the same view just with different data and sometimes, the data can be a subset of what you already had. So I wanted to get to grasps with an MVC approach that would satisfy these wishes and give me a chance to get to know MVC as it is. To this end, I opted to take a look at KnockoutJs as a) it offers what I am looking for and b) it seems to be the most prevalent of MVVM js libraries out there right now. I’m not saying it’s the best or that there aren’t other approaches but as contractor I need to think not just about keeping ahead of the curve, but, in this instance, getting myself up-to-date with it.

I have spent many an hour looking at various approaches covering all aspects of MVC. From the vanilla flavour to a full blown SPA (courtesy of Mr John Papa), I have settled on something in between – I don’t want a clunky ‘return a view every time’ approach, but I don’t feel ready for the single page approach where both the view and data is dynamically grabbed using JavaScript. I love JavaScript for its flexibility but struggle with it because of its flexibility! We C# developers do enjoy the seat-belt constraints of our strongly typed language :)

Before I had even settled on a web approach, I knew that I would want to be able to target more than one front-end and not just via the web so with that in mind, I wanted to abstract my DAL and not just by using EF. I opted to use a POCO domain model with a Code First approach and encapsulate that within a set of Repositories that themselves were house within a UnitOfWork class. I then created a set of services to manage specific areas of logic (but could still overlap), i.e. a CompanyService responsible for basic CRUD ops as well as more specific methods. It is these services that are inject into my controllers via Ninject. Whilst this abstraction provides me with more testable code and allows me to control what operations are performed and how they are performed, it does mean that I lose the more finer points of some of the EF functionality such as Eager Loading etc. However, I have found in development, if something is available, sooner or later, someone will come along and decide to take it, regardless of whether or not it is always needed. Forcing developers through the route of declaring specific business functionality in the service for their needs or simply allowing them to delay load the required resources as and when required minimises the risk of data bloat where each developer adds on their own specific data needs until everyone is complaining of performance issues.

So my layers up to the UI look a little like this:

Domain Model Entities + other common elements (Interfaces, enums etc.)
EF DbContext DbSet<Company>, Fluent API Configurations
Repositories Using generic DataEntityRepository<T>
Unit Of Work Combines all repositories and provides Commit () method
Services CompanyService – i.e. GetAllCompanies()

note: Services is analogous to BLL, not a web or windows service

So, on to the MVC app. I have taken an empty application and applied the Twitter Bootstrap templating to it. I created my own authentication mechanism through the services, based on Forms Authentication. I added KnockoutJs through Nuget and set about creating two initial views – one to list all companies, and one to view details.

Standard controller approach in MVC would be to call the company service, grab all companies, then either inject the result as the model into the View to return or project the results into a DTO first. But as this means that my model is now static on the client side, if I want to manipulate it, I need to return trip to the server.

Take for instance the following scenario:

1. My Index() method in the home controller returns a list of all companies represented as DTOs.

2. My index view has a search text box to allow the user to filter the companies based on a name value.

3. To filter the companies, the user must enter a value, then hit the filter/ search button.

4. The home controller has an Index (string q) method that gets all companies where the name contains the string represented by q. It then returns the Index view again but with a subset of the original data as the model.

It’s a little clunky, isn’t it?

What I really want is for the filter text box to immediately filter the current list as the user types. And for this, I need my model to be available client side.

There are a couple of approaches to do this with Knockout but first off, I went down a web API with an Ajax call approach:

1. HomeController.Index() returns nothing but the view.

2. A new ApiController is created, CompanyController which contains the method, GetAllCompanies and returns an IEnumerable of the DTO representation of a company

3. Index view references a JavaScript file: vm.index.js, that contains the code to call the web API and set up the view model:

   1: $(function () { 

   2:  $.getJSON("/API/company", function (data) {

   3:     var viewModel = 

   4:     {

   5:          //data

   6:          companies: ko.observableArray(ko.toProtectedObservableItemArray(data)),

   7:          filterText: ko.observable(""),

   8:     }; 

   9:     

  10:     viewModel.companyCount = ko.computed(function () {

  11:         if (this.companies() == null) {

  12:             return 0;

  13:         }

  14:         return this.companies().length;

  15:     }, viewModel); 

  16:  

  17:     viewModel.filteredCompanies = ko.computed(function () {

  18:         var filter = this.filterText().toLowerCase();

  19:          if (!filter) {

  20:              return this.companies();

  21:          } else {

  22:              return ko.utils.arrayFilter(this.companies(), function (company) {

  23:                 return company.name().toLowerCase().indexOf(filter) >= 0;

  24:              };

  25:          }

  26:      }, viewModel); 

  27:      ko.applyBindings(viewModel); 

  28:  }); 

  29: });

4. Set up Index View to use the Knockout databinding for both the company list:

   1: <table class="table table-striped">

   2:     <thead>

   3:         <tr>

   4:            <th>Name</th>

   5:             <th>Date Created</th>

   6:             <th>No. of Teams</th>

   7:             <th>Principal Contact</th>

   8:         </tr>

   9:     </thead>

  10:     <tbody data-bind="foreach: filteredCompanies">

  11:         <tr>

  12:             <td data-bind="text: name"></td>                                

  13:             <td data-bind="date: dateCreated, dateFormat: 'DD/MM/YY'"></td>                    

  14:             <td data-bind="text: teamCount"></td>                    

  15:             <td data-bind="text: principalContact"></td>                    

  16:         </tr>

  17:     </tbody>

  18: </table>

5. And the filter text:

   1: <input type="text" data-bind="value: filterText, valueUpdate: 'afterkeydown'" placeholder="filter by name" />

 

Nothing more is needed – the JavaScript grabs the initial data and populates the companies array which in turn populates the filteredCompanies array. The filter text then instigates the refresh of the filteredCompanies array.

This is a much better user experience, not to say more efficient. Granted, we must be careful about how much data we load on to the client side, but this then gives even more weight to using DTOs to minimise the overload on data that is not required.

An area I am not so certain of though is the best approach for getting the data to the client in the first place – here we are using an Ajax call to a web API but firstly, that involves a second trip to the server on top of the initial page request and what about actions where parameters are passed in? Take the details view for instance – it might look something like: /Home/Index/3. The id of 3 would be picked up by the method in the controller, i.e. Index(int id) but how do we get hold of this id were we to make a call through to the corresponding web API method (API/companies/id)?

We could scrape it out of the url I suppose but that seems a little nasty. So perhaps it would be better to allow controller methods to do the necessary work and return the model in the first call and then convert the model into JSON to be used within the client-side JSON:

   1: (function () {

   2:    var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));

   3:    ko.applyBindings(viewModel);

   4: })();

This allows us to have our client-side model to manipulate, minimises the trips to the server for the initial page load and handles the issue of controller action parameters.

The one downside I have found is that where previously I liked to house my view model code in a separate script file, this doesn’t work well with the above conversion code as it cannot process the server-side directive ‘@Html.Raw(….’ outside of the cshtml file itself.

I would love to hear from anyone else who has a preference on how best to approach this.

Adding Unique Constraint to column using EF Code First

First of all, it has been a very long time since this blog was last active. About 2 and a half years in all. That’s also the same age as my daughter. Spare time? What is that, exactly?!

Anyway, I have recently been working on my own project and decided to dive deeper into the Code First approach of Entity Framework. In particular, I do like the idea of being able to design your entities in an OO fashion and have that matched in the Database. This is more appealing when you can use the Fluent API to manage relational rules such as required properties without contaminating the core entity itself. I like it a lot.

However, I came a cropper the other day when I decided I wanted to add a Unique constraint on to the Name property of my Company table. Not an unusual request, so I was a little baffled as to why I did not have the following as an operation in Fluent API:

   1: public CompanyConfiguration()

   2: {

   3:     Property(x => x.Name).IsUnique();

   4:     Property(x => x.Name).IsRequired();

   5:     Property(x => x.Name).HasMaxLength(256);

   6: }

 

BTW, this is part of a Configuration class based on EntityTypeConfiguration<T>. The line that did not compile is the IsUnique() one.

Digging around on the web, I noticed that such functionality was planned for EF 5.0 but got pulled. My suspicions lie around the fact that this is a table constraint, rather than a field attribute so it would have more of an impact on how it is used. Either way, I had a look at how people worked around this and a common approach was to execute an “ALTER TABLE…..” command somewhere sensible such as the Database Initializer class. This was the approach I decided to take myself but I wanted to do so in a way that allowed a more DRY approach for any property in any class I wanted to set a Unique constraint on

The result was the following method in my DbContext Initializer class:

   1: private void AddUniqueConstraint<T>(Expression<Func<object>> expression) 

   2:             where T : DataEntityBase

   3: {

   4:    var columnName = String.Empty;

   5:  

   6:    if (expression.Body is MemberExpression)

   7:    {

   8:        columnName = ((MemberExpression)(expression.Body)).Member.Name;

   9:    }

  10:    else if (expression.Body is UnaryExpression)

  11:    {

  12:        columnName = ((MemberExpression)(((UnaryExpression)(expression.Body)).Operand)).Member.Name;                

  13:    }

  14:  

  15:    var script = "ALTER TABLE {0} ADD CONSTRAINT uc_{1} UNIQUE ({1})".FormatWith(Pluralizer.Pluralize(typeof(T).Name), columnName);

  16:    _context.Database.ExecuteSqlCommand(script);

  17: }

It’s not entirely tidy – you have to create an instance of the class in order to pass in the property name so perhaps someone out there can recommend a different approach – maybe using reflection?

In any case, it’s doing a job for me. For reference, GlobalContext is my DbContext class, DataEntityBase is an abstract class that holds common properties for classes to be added to the Database and FormatWith is simply a String extension method I use in preference to String.Format(“…”) etc.

note: my original approach to resolving the property name was flawed in so much as it would throw an exception if the expression.Body was a UnaryExpression, not a MemberExpression. I have since rectified this and updated the post accordingly.