In my MVC 4 Fundamentals video I have a section using the ASP.NET Web API on the server with jQuery and Handlebars on the client to build a somewhat interactive UI. A few people have asked what the code would look like with AngularJS.
The first part of the example, display a list of videos, is easy with Angular. Here is the HTML:
<div ng-app ng-controller="VideoController">
<table>
<thead>
<th>Title</th>
<th>Length</th>
<th></th>
</thead>
<tbody>
<tr data-id="{{video.Id}}" ng-repeat="video in videos">
<td>{{video.Title}}</td>
<td>{{video.Length}}</td>
<td>
<button class="editVideo">Edit</button>
<button class="deleteVideo">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
The ng-app directive represents the application "root" for angular. Most applications would have ng-app on the body element, or the top html element, but you can also root the application further into the DOM. The ng-controller directive provides the name of a controller function for Angular to find and invoke. The controller provides the model and allows us to use data binding in between the model and the view (the HTML).
The controller function looks like this:
var VideoController = function($scope,$http) {
$http.get('/api/videos/').success(function(data) {
$scope.videos = data;
});
};
Angular will inject the $scope and $http parameters into the controller (names are significant). $scope is where we can place the model, while $http is a service that provides low-level HTTP communication (we'll see a higher level service in a later post). The above code is calling a Web API controller on the server to retrieve a list of videos, and placing them into the $scope when the call is successful. Back in the HTML, an ng-repeater will loop through the videos when they become available (Angular knows when the model changes), and outputs table rows with video information (via {{ }} templates).
The above is a quick demonstration of why I like Angular. It's quick, clean, and easy to learn. In my original demo I also inserted, deleted, and edited videos. We'll take a look at these scenarios next.
The Kata repository has new additions.
The Refactoring kata I pushed out last year now has a Java version available (thanks, Tom!).
Related to the previous post, I also added a Composition Kata. Excerpt from the README:
One day a developer was writing some logic to perform calculations on a collection of Measurement objects with X and Y properties. The developer knew the business would need different types of aggregations performed on the collection (sometimes a simple sum, sometimes an average), and the business would also want to filter measures (sometimes removing low values, sometimes removing high values).
The developer wanted to make sure all algorithms for calculating a result would filter a collection of measurements before aggregation. After consulting with a book on design patterns, the developer decided the Template Method pattern would be
ideal for enforcing a certain ordering on operations while still allowing subclasses to override and change the actual filtering and the calculations.
public abstract class PointsAggregator
{
protected PointsAggregator(IEnumerable<Measurement> measurements)
{
Measurements = measurements;
}
public virtual Measurement Aggregate()
{
var measurements = Measurements;
measurements = FilterMeasurements(measurements);
return AggregateMeasurements(measurements);
}
protected abstract IEnumerable<Measurement> FilterMeasurements(IEnumerable<Measurement> measurements);
protected abstract Measurement AggregateMeasurements(IEnumerable<Measurement> measurements);
protected readonly IEnumerable<Measurement> Measurements;
}
From this base class the developer started creating different classes to represent different calculations (along with unit tests).
Your job is to create a new calculation. A calculation to filter out measurements with low values and then sum the X and Y values of the remaining measurements. You'll find details in the comments of the code, and the unit tests.
You'll implement the calculation twice. Once by building on top of the Template Method approach (in the Inheritance folder), and once with a compositional approach (in the Composition folder). When you are finished and all of the tests pass (9 total, you'll start with 6), take some time to reflect on the different approaches.
- Which are the drawbacks and benefits to each?
- Which one would you rather build on in the future?
It was about 12 years ago when I helped to write an application that featured a class hierarchy like the following:

I remember the code because I was the one to refactor the application to build the class hierarchy in an attempt to remove duplicated code.
I believed what I was creating was a better application.
What I actually created was a model where other developers struggled to understand when a virtual method override would kick in. They had to work hard to figure out when to properly call a base class method. All changes inside the hierarchy were like moving balanced blocks of wood in a game of Jenga. Someone eventually has to lose a game of Jenga. You just hope the structure stays stable enough to make it through through your turn.
As a kid my parents told me not to play with matches, not to go near the dog chained to the oak tree down the street, and to always hold on to the handrail when the back porch steps were wet.
As a kid, I didn't understand why my parents told me these things until I was burned, or chewed, or contemplating life during a cartwheeling descent of rain slickened steps.
Similarly, I believe there are some aspects of software development that you have to experience to truly appreciate. I've been looking for a good example where composition clearly trumps inheritance, and might have something that is contrived, of course, but reasonable enough to demonstrate the principle and demonstrate some of the pain.
Coming up next – the Composition Kata.
If you like choices, you've come at the right time. You might think the decision making process starts by choosing between ASP.NET Web Forms and ASP.NET MVC, but if you widen your perspective a bit you'll find there are even more options outside the confines of the File –> New Project dialog in Visual Studio. And, these choices have steadily increased and matured over the last few years.
Here are just a few of the other options for writing a web app today:
- Nancy (lightweight and low ceremony)
- FubuMVC (convention-based and highly compositional)
- OpenRasta (a resource oriented framework for web sites and APIs)
- Service Stack (a web services framework)
- Oak (highly dynamic, frictionless)
Even when you restrict yourself to frameworks from Microsoft, there are still a bewildering number of decisions to make. Web Pages, Web Forms, Web API, or MVC?
Ultimately your job is to ship working software, and be happy about shipping the software. It's hard to build an application when you loathe working with the underlying technology. If you are brand new to all of this, I believe one of the first steps is to sit down by yourself and with your team, and figure out what you like and dislike about the available frameworks. If you are brand new to all of them, it would be worthwhile to spend a couple hours with each. Read about their design goals. Read the code examples as they will demonstrate the code you'll be living with.
Some of the questions to ask at this period include:
- What are my business requirements? Do I need to optimize for both mobile and desktop? Do I need to be highly scalable? What sort of authentication mechanisms do I need for my customers? Am I building a site, a service, or a combination of both?
- Do the abstractions make sense to me? Do the abstractions relate well with my mental modal of how things work on the web?
- What do I value the most? Testability? Flexibility? Simplicity? Past experience with an existing framework?
- What are my technology requirements? Am I tied to IIS and Windows or do I want the ability to run on Mono? Do I need to build an application that makes heavy use of JavaScript in the browser?
You have to answer these types of questions and narrow down the field based on how you perceive the capabilities of each framework. You can build almost anything with any of the above.
Eventually I'd recommend narrowing selections down to 2 or maybe 3 frameworks, then writing some code with each to get a good feeling for a what life with the framework is like.
When people ask me what to use, I tell them the choice of framework (and language) is a very personal choice. You have to evaluate questions like the questions listed above to figure out for yourself what framework will be the best for you, your team, and your business.
There are only a few hard and fast rules I can proclaim on this day in the month of February in the year 2013.
When starting a new application today:
- Do not use Silverlight
- Do not use LINQ to SQL
- Do not use WCF, unless you have no other option (e.g, to build a SOAP API).
- Do not use the Web Forms view engine for anything but a Web Forms application
- Don't forget: in larger applications the web layer is just a façade. Other architectural decisions should probably have a higher priority.
I have a new set of videos on Pluralsight covering the Twitter Bootstrap framework.
Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development. In this course we'll see how to use Bootstrap's CSS and JavaScript to turn plain HTML into navigational menus, picture carousels, split buttons, alerts, modal dialogs, and more.
If there is enough interest, I was thinking of a future set of videos showing how to use Bootstrap's LESS files with a server framework like ASP.NET MVC.
The SqlBulkCopy class is invaluable for moving large amounts of data into SQL Server from a .NET application. I've been working with the class recently and taking notes on a few quirks and features.
Like most other areas of the .NET framework, SqlBulkCopy provides await-able methods for C# 5. In fact, the number of awaits in a bulk copy operation is remarkable (3 awaits across 4 async calls):
public async Task Execute()
{
using(var sourceConnection = new SqlConnection(_sourceConnectionString))
using(var targetConnection = new SqlConnection(_targetConnectionString))
using(var sourceCommand = new SqlCommand(_selectQuery, sourceConnection))
using(var bulkCopy = new SqlBulkCopy(targetConnection))
{
await Task.WhenAll(sourceConnection.OpenAsync(),
targetConnection.OpenAsync());
var reader = await sourceCommand.ExecuteReaderAsync();
bulkCopy.DestinationTableName = _targetTable;
await bulkCopy.WriteToServerAsync(reader);
}
}
An obvious statistic you'll want to know about is how many total records have moved into the target table. Unfortunately, SqlBulkCopy makes this difficult. Although the class does have a SqlRowsCopied event, the event doesn't fire at the end of execution, but only on every N number of records (where N is configurable). Thus, if N is set to 50,000, you'll know when you copy 50,0000 records and 100,000 records, but won't know if you copied 29,000 more records after the first 50,000.
bulkCopy.NotifyAfter = 50000;
bulkCopy.SqlRowsCopied += (sender, args) =>
{
Console.WriteLine(args.RowsCopied);
};
There are several workarounds, as suggested in a StackOverflow post:
- Use reflection to dig out the value of _rowsCopied (a private field in a SqlBulkCopy object).
- Execute a SELECT COUNT on the target table after the bulk copy completes (possibly not accurate).
- Provide your own wrapper/adapter for IDataReader and count the number of MoveNext calls with your own code. This is slightly painful since you can't inherit from SqlDataReader (because of an internal constructor), and need to implement dozens of methods on IDataReader (just forwarding calls to the inner reader). It's scenarios like this where I wish C# had an easy way to delegate member invocations (like Groovy).
SqlBulkCopy is particular about matching columns in the source and destination, so chances are you won't be able to bulk copy without configuring a column mapping for the operation. SqlBulkCopy is also particular about data types, and here there is limited flexibility in code. For example, if you want to copy a NULL value into a textual destination column, you'd think it would this easy:
SELECT Column1, NULL as Column2, Column3 FROM Table
This gives a runtime error, however:
System.InvalidOperationException: The locale id '0' of the source column and the locale id '1033' of the destination column do not match.
The only way I found to avoid the error is to make sure the NULL value is a "textual" NULL value (where the CAST type doesn't have to exactly match the destination column type, i.e. for this example the destination could be nchar(10), but the query still works):
SELECT Column1, CAST(NULL as varchar(1)) as Column2, Column3 FROM Table
Numbers can also present some difficulties. If I want to copy a decimal(20,7) column to a decimal(20,7) column there is no problem, but if I want to aggregate a decimal(20,7) column and place the result into a decimal(20,7) column, there will be an exception. In other words, the following query:
SELECT Column1, SUM(aColumn) as Column2 ...
Will throw an InvalidOperationException (The given value of type SqlDecimal from the data source cannot be converted to type decimal of the specified target column.). I believe this is because SUM takes a decimal(20,7) and returns a decimal(38,7). Again, the only work around I found was an explicit convert in the query to keep the data types as decimal(20,7).
Hope that helps anyone working with SqlBulkCopy.
Recently I was asked to look at a "I click and the wrong thing happens" type error. I didn't know the codebase, and I wanted to start by seeing the JavaScript for the click event handler. In a project with thousands of lines of JavaScript this can be hard, but I found Visual Event 2 after a little searching and the tool took me right to the code.
Visual Event 2 is a bookmarklet, so the install is as simple as dragging a link into the bookmark area of a browser (though it took some hunting to find the link on the Visual Event 2 page - look under the section titled Make It Go).
Once I got to the page with a problem, I clicked the bookmark and the tool found all the events wired in the DOM. ![]()
All of the DOM elements with events attached become color coded, and I could hover over elements for details. In most cases, Visual Event could give me the exact line and file where the event handler lives.
Unlike the Event Listeners tab in Chrome developer tools, Visual Event understands jQuery events (even live events), as well as YUI, MooTools, Prototype, and more.
Great tool, and free!