A couple of days ago we posted a new set of NuGet packages and today we posted a new tools installer for WCF Data Services 5.2.0-rc1. This prerelease integrates the UriParser from ODataLib Contrib and fixes a few bugs.

What is in the prerelease

This prerelease contains the following noteworthy bug fixes:

  • Fixes an issue where code gen for exceedingly large models would cause VS to crash
  • Provides a better error message when the service model exposes enum properties
  • Fixes an issue where IgnoreMissingProperties did not work properly with the new JSON format
  • Fixes an issue where an Atom response is unable to be read if the client is set to use the new JSON format

URI Parser

In this release ODataLib now provides a way to parse filter and orderby expressions into a metadata-bound abstract syntax tree (AST). This functionality is typically intended to be consumed by higher level libraries such as WCF Data Services and Web API.

To parse a filter expression, use the following method on the new class ODataUriParser:

public static FilterClause ParseFilter(
    string filter,
    IEdmModel model,
    IEdmType elementType,
    IEdmEntitySet entitySet)

The ParseFilter method returns a FilterClause object. The Expression property on the FilterClause contains the root node of the AST that represents the filter expression. In order to walk the AST, use the Visitor pattern to handle an arbitrary QueryNode by examining the Kind property, and then casting accordingly. For instance:

switch (node.Kind)
{
    case QueryNodeKind.BinaryOperator:
        return Visit((BinaryOperatorNode)node);
    case QueryNodeKind.UnaryOperator:
        return Visit((UnaryOperatorNode)node);
    case QueryNodeKind.SingleValuePropertyAccess:
        return Visit((SingleValuePropertyAccessNode)node);
     // And so on...
}

Let’s say the filter string was "Name eq 'Bob'", and Name is a property on the elementType provided to ParseFilter.  This expression is represented by a BinaryOperatorNode. The BinaryOperatorNode has a Left expression, which is a SingleValuePropertyAccessNode, capturing the Name property, and a Right expression, which is a ConstantNode, capturing the string literal 'Bob'

To parse an orderby expression, use ODataUriParser.ParseOrderBy. This method is very similar to ParseFilter. The resulting OrderByClause also has an Expression property, which is an AST just like FilterClause. Since an $orderby system query option can specify more than one ordering expression, there is a ThenBy property on OrderByClause that points to the next OrderByClause. So in essence, you get a linked list of OrderByClause objects. For example, the string "Name asc, ShoeSize desc" would result in an OrderByClause with an Expression capturing the Name property, and a ThenBy property pointing to another OrderByClause capturing the intent to order by the ShoeSize in descending order.

For a more detailed write-up on filter and orderby parsing, read this blog post.

Feedback Please

We’d love to hear how well this release works for your service. Even if you don’t need the URI Parser functionality, please consider trying these new bits and providing us with feedback whether everything goes perfectly or you run into problems. As always, please feel free to leave a comment below or e-mail me directly at mastaffo@microsoft.com.