Databinding from an ASP.NET Page Method with Knockout

Last week, I wrote a brief post about how easy it is to do databinding with Knockout. The article presents a barebones example, but it fails to address an important issue: how to get data into the view model.

I live in a .NET world, and I’m usually working with small ASP.NET application. I’ve found that page methods are an easy and convenient way to get to the data I need. They’re easily accessible via jQuery, too. So let’s see how we can get data from an ASP.NET page method using jQuery and pass it along to our Knockout view model.

First, let’s get to know our page method. I created a simple Status class that will be returned from a page method, GetStatus. Here’s the entire code-behind for my page:

using System;
using System.Web.Services;

namespace adamprescott.net.Knockout
{
    public class Status
    {
        public bool HappyFlag { get; set; }
        public string Text { get; set; }
    }

    public partial class Default : System.Web.UI.Page
    {
        [WebMethod]
        public static Status GetStatus()
        {
            return new Status { HappyFlag = true, Text = "This just a default" };
        }
    }
}

We know what data we’re getting, so we can go ahead and create our view model and UI. Here’s what that looks like:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="adamprescott.net.Knockout.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-2.0.2.min.js"></script>
    <script src="Scripts/knockout-2.2.1.js"></script>
    <script type="text/javascript">
        $(function () {
            var viewModel = {
                isHappy: ko.observable(),
                statusText: ko.observable(),
            };
            ko.applyBindings(viewModel);
            
            // todo: get data from page method
        });
    </script>
</head>
<body>
    <input data-bind="value: statusText" /><br/>
    Happy? <input data-bind="checked: isHappy" type="checkbox" />
</body>
</html>

All that’s left is for us to do is call the page method and update the values in our view model. And, as I said before, jQuery makes it a snap!

$.ajax({
    type: "POST",
    url: "Default.aspx/GetStatus",
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (result) {
        var data = result.d;
        viewModel.isHappy(data.HappyFlag);
        viewModel.statusText(data.Text);
    }
});

With that, we’re done. When the page loads, the view model is created and bound to the UI controls. We then make an asynchronous call to the page method using jQuery and update the values in our view model.

Here’s the complete ASPX file:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="adamprescott.net.Knockout.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-2.0.2.min.js"></script>
    <script src="Scripts/knockout-2.2.1.js"></script>
    <script type="text/javascript">
        $(function () {
            var viewModel = {
                isHappy: ko.observable(),
                statusText: ko.observable(),
            };
            ko.applyBindings(viewModel);
            
            $.ajax({
                type: "POST",
                url: "Default.aspx/GetStatus",
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (result) {
                    var data = result.d;
                    viewModel.isHappy(data.HappyFlag);
                    viewModel.statusText(data.Text);
                }
            });
        });
    </script>
</head>
<body>
    <input data-bind="value: statusText" /><br/>
    Happy? <input data-bind="checked: isHappy" type="checkbox" />
</body>
</html>

LINQ to XML Descendants Versus Elements

LINQ to XML is the greatest thing for working with XML. If you’re doing just about anything XML in .NET, you should probably be using it. One of the points I missed in the passed was the difference between LINQ to XML’s Elements and Descendants methods. Both methods are used to retrieve sub-elements, but the distinction is that Elements will only search direct child nodes whereas Descendants will search recursively.

Consider the following XML:

<root>
  <house>
    <address>123 Number Lane</address>
  </house>
  <business>
    <address>100 Fun Drive</address>
  </business>
</root>

If I want to retrieve a list of all addresses, I can use Descendants.

var addresses = xml.Descendants("address");

// Result:
// <address>123 Number Lane</address>
// <address>100 Fun Drive</address>

I can’t do this with Elements.

var addresses = xml.Elements("address");

// Result:
// (Nothing!)

If I want to accomplish this with Elements, I need to first get all children from the root and then retrieve their addresses.

// You should probably just use Descendants()...
addresses = xml.Root
	.Elements()
	.SelectMany(x => x.Elements("address"));

// Result:
// <address>123 Number Lane</address>
// <address>100 Fun Drive</address>

Elements is good for getting values from a specific path, though. For example, if you want to retrieve only the house addresses, you could do the following:

addresses = xml.Root
	.Elements("house")
	.SelectMany(x => x.Elements("address"));

// Result:
// <address>123 Number Lane</address>

Note, however, that the same* task can be accomplished using Descendants, too!

addresses = xml.Root
	.Descendants("house")
	.SelectMany(x => x.Descendants("address"));

// Result:
// <address>123 Number Lane</address>

*Of course, this “same” functionality is entirely dependent on the structure of the XML and what you’re trying to accomplish. If there were child elements beneath “house” that had child addresses, Descendants would snag those, which may or may not be desirable depending on your needs.

So, in summary, use Elements when you want to search and retrieve only from immediate child elements (perhaps it should have been named “Children!”), and use Descendants when you want to search and retrieve from all descendant elements. I generally stick to Descendants because I can “jump” directly to the node(s) that I’m looking for without having to step though the path. If I only care about a specific path, I can specify it with Descendants the same as I would with Elements. I only use Elements if I needed to find elements at a specific level or want to ignore matching sub-elements.

Two-Way Databinding with Knockout

Earlier this week, I wrote a post about two-way databinding with jQuery. I was looking for a fast & elegant way to do it, but I came up somewhat empty. A lot of what I was finding suggested using a different plug-in or framework, such as Knockout. I decided to give Knockout a whirl, and I’m an instant fan.

My favorite part is how the binding occurs declaratively in the HTML.

<input data-bind="checked: boolValue" type="checkbox" />
<input data-bind="value: textValue" />

That’s all you need to bind the values to the controls–nice, right!? Okay, but this is javascript, so what’s going on at the top? Surely, it’s a mess. Nope, it’s just as easy. Just create a view model and call Knockout’s applyBindings method.

var viewModel = {
    boolValue: ko.observable(true),
    textValue: ko.observable("Hello!")
};
ko.applyBindings(viewModel);

That’s it, I promise. To show that there’s nothing up my sleeve, here’s the entire page:

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-2.0.2.min.js"></script>
    <script src="Scripts/knockout-2.2.1.js"></script>
    <script type="text/javascript">
        $(function () {
            var viewModel = {
                boolValue: ko.observable(true),
                textValue: ko.observable("Hello!")
            };
            ko.applyBindings(viewModel);
        });
    </script>
</head>
<body>
    <input data-bind="checked: boolValue" type="checkbox" />
    <input data-bind="value: textValue" />
    
    <div>The value of boolValue is <span data-bind="text: boolValue"></span></div>
    <div>The value of textValue is <span data-bind="text: textValue"></span></div>
</body>
</html>

The Knockout site has really good interactive tutorials for getting started. If you’re interested in learning or exploring further, definitely start there.

PivotTable Limits in Excel

Yesterday morning, I was creating a sweet pivot table to measure our development teams’ velocity over time. I had a track-everything spreadsheet that has all the User Stories and Tasks from our TFS Team Project. When I created my pivot table, I wasn’t getting all the values, though!

I did some quick Googling and quickly learned that Excel has limits to the amount of data that can be crunched in a pivot table. Who knew!?

I’m using Excel 2013, and I wasn’t able to find information about the exact limit. Earlier versions of Excel were limited to 32,000 fields across all rows and columns. The specification for Excel 2010 vaguely states that it’s “limited by available memory.” I’m not sure what that means, but I had 22 fields and over 4,000 rows, so I assumed that was my problem.

In order to test this theory, I created a new, smaller query with just the fields I needed for my pivot table. Sure enough, with the smaller data set, everything showed up. And I guess that’s the moral of this story: if you’re missing data from your pivot table, and you’ve got a pretty big data set, you’re probably exceeding the limits.

Two-Way Databinding with jQuery

I was working on a small data entry page and wanted to use jQuery to databind an object to my controls. I was expecting a simple command, like $(“#myControl”).databind(obj.Value), but was surprised to find that one did not exist. The Internet kept telling me to look elsewhere–mostly Knockout–but I was sure that this could be accomplished with jQuery alone.

It turns out that it is easy to do with jQuery, but it’s all manual. I created a function named databind and, for each control, I populate it with the desired property’s value and create an event handler to update the value when the control changes.

function databind() {
    var ctl;

    // a checkbox
    ctl = $("#uxMyCheckbox");
    ctl.attr('checked', model.BoolValue);
    ctl.change(function () { model.BoolValue = this.checked; });

    // a textbox
    ctl = $("#uxMyTextbox");
    ctl.val(model.TextValue);
    ctl.change(function () { model.TextValue = this.value; });
}

It’s not quite as elegant as I was hoping for, but it’ll do for now. I’ll probably check out Knockout for the future, though.

“Any fool can write code…

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

I found this guy while researching the use of var following a spirited debate with co-workers. (In case you’re wondering, I’m pro-var. Viva la var!)

Getting Started with Web API

I first heard about ASP.NET Web API several months ago in MSDN magazine. My primary role is architecting cross-product solutions between my company’s customers and other software vendors, so I was instantly interested. The “wow” part for me was that the consumer can specify whether they’d like to communicate using JSON or XML, and Web API does the rest. The MVC-like structure promises improved unit-testability, and I’m excited to simplify access to our data for third parties on all platforms by leveraging HTTP.

And so, I created my first “Hello, world”-style application. In terms of creating the Web API service, I just followed MSDN’s Your First ASP.NET Web API tutorial. It’s very easy to follow, and I recommend starting there.

Overly-Summarized Tutorial

To get you somewhat up to speed, here’s a so-summarized-that-it’s-probably-not-even-useful summary of the tutorial. A functional web API is created by defining a control that derives from ApiController.

namespace HelloWebAPI.Controllers
{
    using HelloWebAPI.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;

    public class ProductsController : ApiController
    {

        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }

        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(
                (p) => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

Routing will map the controller methods to URIs as follows:

Controller Method URI
GetAllProducts /api/products
GetProductById /api/products/id
GetProductsByCategory /api/products/?category=category

Finally, the API can be accessed using JavaScript/jQuery like so:

    <script type="text/javascript">
        $(document).ready(function () {
            // Send an AJAX request
            $.getJSON("api/products/",
            function (data) {
                // On success, 'data' contains a list of products.
                $.each(data, function (key, val) {

                    // Format the text to display.
                    var str = val.Name + ': $' + val.Price;

                    // Add a list item for the product.
                    $('<li/>', { text: str })    
                    .appendTo($('#products'));   
                });
            });
        });
        
        function find() {
            var id = $('#prodId').val();
            $.getJSON("api/products/" + id,
                function (data) {
                    var str = data.Name + ': $' + data.Price;
                    $('#product').text(str);
                })
            .fail(
                function (jqXHR, textStatus, err) {
                    $('#product').text('Error: ' + err); 
                });
        }   
    </script>

Accepting Complex Types

The tutorial is great, but the controller methods only accept integers and strings. I need to accept and process complex types in order to do most tasks, like record searching and updating. It took me a little bit of Googling and trial & error to figure out, but I was able to modify the tutorial example to accept a complex object with minimal changes.

The first thing I needed was a complex type. I created an empty class named GetDto. I then added the new parameter to the GetProductById method in the controller. The final step was adding the HttpPost attribute to the method. (A POST request must be used since complex objects must be read from the request body, and GET requests do not have a body.) That’s it for the controller changes. In order to test, I added a name field to my DTO and appended it to the response.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using HelloWebApi.Models;

namespace HelloWebApi.Controllers
{
    public class GetDto
    {
        public string name { get; set; }
    }

    public class ProductsController : ApiController
    {
        Product[] products = new Product[] 
        { 
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        [HttpPost]
        public Product GetProductById(int id, GetDto dto)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            product.Name += dto.name;
            return product;
        }

        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(
                (p) => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

The modifications to the calling jQuery code were less intuitive because the tutorial used the getJSON method. I had to rewrite that code to use the ajax method, so the request would be sent as a POST with my complex object sent as the request body. Here’s what I came up with:

    <script type="text/javascript">
        $(document).ready(function () {
            // Send an AJAX request
            $.getJSON("api/products/",
            function (data) {
                // On success, 'data' contains a list of products.
                $.each(data, function (key, val) {

                    // Format the text to display.
                    var str = val.Name + ': $' + val.Price;

                    // Add a list item for the product.
                    $('<li/>', { text: str })    
                    .appendTo($('#products'));   
                });
            });
        });
        
        function find() {
            var id = $('#prodId').val();
            $.ajax({
                url: "api/products/" + id,
                type: "POST",
                data: JSON.stringify({ name: id }),
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    var str = data.Name + ': $' + data.Price;
                    $('#product').text(str);
                }
            });
        }   
    </script>

Calling from C#

jQuery is nice and all, but most of the work I do is C#. So my final goal for this first look was to invoke the API from C#. I created a simple WPF test app and used another MSDN tutorial, Calling a Web API From a WPF Application. This tutorial was also quite good, so I won’t get into too much detail. Here’s the end result that allows me to access my service from within my WPF application. Easy-peasy.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Windows;
using HelloWebApi.Models;

namespace HelloWebApiTestClient
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void OnTestClick(object sender, RoutedEventArgs e)
        {
            HttpClient client = new HttpClient();
            ProductsCollection _products = new ProductsCollection();

            client.BaseAddress = new Uri("http://localhost:14095");
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

        
            try
            {
                btnGetProducts.IsEnabled = false;

                var response = await client.GetAsync("api/products");
                response.EnsureSuccessStatusCode(); // Throw on error code.

                var products = await response.Content.ReadAsAsync<IEnumerable<Product>>();
                _products.CopyFrom(products);
            }
            catch (Newtonsoft.Json.JsonException jEx)
            {
                // This exception indicates a problem deserializing the request body.
                MessageBox.Show(jEx.Message);
            }
            catch (HttpRequestException ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                btnGetProducts.IsEnabled = true;
            }
        }
    }
}

Next Up: Security

I’m pretty happy with what I’ve seen so far. I watched a webcast on how easy it is to secure Web API using a variety of methods. So that’s what’s next for me. Yay for new stuff!

Write Tests First–But Not ALL Tests First

I’ve been preaching hard about test-driven development and the importance of writing tests first. I can feel the culture beginning to shift as people are slowly starting to buy in, but I had an interesting discovery yesterday.

I was invited to a meeting by some developers that wanted me to walk through how I would’ve used test-driven development to write tests and develop a new project that they had recently started. It was essentially a data validation project that retrieved data from the database, checked it against a set of rules, and recorded any violations. We were reviewing a Controller class that was responsible for orchestrating the operation.

“Okay,” I said, “What is this thing supposed to do?”

The developers told me it retrieves records, validates each record, and saves the validation results. So, without knowing anything more than that, I figured there were at least two external dependencies: an IDataAccess responsible for retrieving records and saving the result and an IValidator that does the data validation/rule-checking. I drew a diagram on the whiteboard to show the relationships between the Controller and these two components.

I explained that since we know the dependencies and how we expect them to be used, we can begin to write tests. We also need to know how our application should react when the dependencies are missing. I started to rattle off some tests:

  • ProcessRecords_NullDataAccess_ThrowsArgumentNullException
  • ProcessRecords_NullValidator_ThrowsArgumentNullException
  • ProcessRecords_DataAccessReturnsNonEmptyList_ValidatesEachRecord
  • Etc.

The group was with me, but they quickly shifted focus to what tests were needed for the DataAccess class. And the tests for its dependencies. And everything else.

“Whoa, whoa, WHOA. None of that matters for this. All we care about is this method,” I say.

“Well, yes, but we want to do test-driven development. We thought the goal was to have all of our tests written first so we can go back and implement them.”

That’s when I had my epiphany. When I’m telling people to write tests first, they think I mean write ALL tests first. This is not the case! It would be virtually impossible to think about every code decision and execution path for an entire method/class/application upfront, and I think that’s where there’s been a disconnect. I can look at the finished code and come up with all the tests, but there is no way I could’ve come up with every single test for every single method before ever writing any code.

I went to another small team of developers and asked them if they also thought I meant “all tests first.” They did. It’s disappointing to know that I was sending the wrong message, but I’m glad I have something to address that will hopefully result in more passengers on the TDD train.

When you’re getting started with test-driven development, don’t try to write every single test first. Don’t even try to write as many tests as you can think of. You just want to write tests as you go. What does this method need to do next? Write a failing test, then write the implementation to make it pass. Red, green, refactor, baby! I’m also exchanging my “tests first” mantra for a new one: “test as you go!”

The Pitter-Patter of Little Feet in the Office

Our yearly batch of summer interns arrived last week. I always struggle with how to get a large group of fresh faces up to speed quickly. The challenge is coming up with an agenda that keeps everybody busy with educational, engaging activities without overloading them. This year, I did my best to plan a mix of product demos and classroom-style programming lectures. This year went smoother than years past, but I’d say it was still only marginally successful.

We have a suite of products that I wanted to expose the group to. So, each day, I scheduled a 1-hour demo with a different application. The interns liked seeing the different products but felt that the demos went too deep and provided too much redundant information. Fair enough. I’m usually hesitant to do too many product demos with new hires because it’s so much information that very little is retained. Instead, it might be better give the demos at a much higher level. So that’s lesson number one: talk about the purpose of the applications and their primary modules instead of going through each module and all of its sub-modules.

The other half of my “curriculum” revolved around our development tools, processes, and practices. I covered a different topic each day: Monday was an overview of tools (Visual Studio, SQL Server Management Studio, etc.); Tuesday we talked about object-oriented programming; Wednesday was an introduction to unit testing; Thursday was test-driven development and unit test mocks; and Friday was agile development. I wasn’t sure how high or low level to go with a lot of these because I wasn’t sure how much exposure the interns had to any of these topics.

The tools overview was probably the least useful session. I know that most colleges aren’t working with .NET and Visual Studio, so I wanted to go through the IDE and cover how to do basic tasks as well as highlight some of the less obvious features that I like. The problem here is that the basic functionality is self-explanatory and the advanced features can’t be appreciated until you’ve used the software for a bit. We use SQL Server, too, so I wanted to breeze through SQL Server Management Studio. I had the same problem there–people who knew what I was talking about already knew what I was showing them, and people who didn’t know SQL were nodding along but probably not processing. So at the end of the day, that was somewhat of a bust.

The other sessions went better. When I covered object-oriented programming, I just tried to stress SOLID design principles. I also discussed the important of usability over reusability and quickly touched on code smells. I think the message was clear: SOLID + low odor = good. The introduction to unit testing was good, too. I was surprised to see that more than half of our interns had done unit testing as part of their school work. I’m glad to see this sneaking into college courses. The test-driven session that followed also went well, and it turned into a demonstration of mocks. None of the interns had seen mocks before, and I think they were generally excited with what they saw. The final session of the week was about agile. I shared my thoughts on what makes a good story and how the stories drive work from sprint to sprint. The agile stuff went okay–lots of nodding–but the conversation turned into more of a Q&A for me. The interns were interested in how I learned all that I know, and I was happy to share my experiences and insights that have helped me enjoy a successful career so far.

Overall, I’d say it was a pretty good week. There was still a bit too much time where the interns weren’t sure what they should be working on, but it was a more organized first week than we’ve had in the past. I’m satisfied with how it went, but I have plenty of ideas on how to make it better next year.

I’m interested to know what the first week for interns looks like at other companies. What sorts of activities do you plan? How do you introduce them to your product(s)? What do you do to get them up to speed and productive? And what do you do to keep it fun?