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.

Advertisements

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.

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!