<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Meta-Me</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/alexj/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/alexj/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 24 Feb 2016 09:30:36 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Parsing OData Paths, $select and $expand using the ODataUriParser</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/parsing-odata-paths-select-and-expand-using-the-odatauriparser</link>
      <pubDate>Fri, 10 May 2013 10:35:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2013/05/10/parsing-odata-paths-select-and-expand-using-the-odatauriparser/</guid>
      <description><![CDATA[UPDATE: This post was updated on May 29th 2013 to reflect changes to simplify the SelectExpandClause...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: x-small;"><span style="color: rgb(128, 128, 128);"><em><strong>UPDATE</strong>: This post was updated on May 29th 2013 to reflect changes to simplify the SelectExpandClause API between 5.5 beta and 5.5 RTM Release, the biggest change involved merging Select and Expand into SelectedItems.</em></span></span></p>  <p>The <strong>ODataUriParser</strong> is continuing its march towards completion. In fact in <strong>ODataLib</strong> version 5.5 (RTM drops on May 29th) it is almost complete.</p>  <p>In the <a href="http://blogs.msdn.com/b/alexj/archive/2012/12/06/parsing-filter-and-orderby-using-the-odatauriparser.aspx">last post</a> I talked about how you could parse <strong>$filter</strong> and <strong>$orderby</strong>. In 5.5 you can also parse <strong>$select</strong>, <strong>$expand</strong> and the path part of an OData url too. Which means all that remains it putting all these bits together into a method that will parse the whole Url with a single step.</p>  <p>That said with 5.5 you can do this yourself, the algorithm is essentially:</p>  <ol>   <li>Parse the Uri path into an <strong>ODataPath</strong> <span style="color: rgb(0, 0, 255);">(see below)</span></li>    <li>Use the <strong>Type</strong> and <strong>IEdmEntitySet</strong> of the <strong>ODataPath</strong> to:</li>    <ol>     <li>Parse <strong>$filter</strong> clause <span style="color: rgb(128, 128, 128);"><em>– Use ODataPathParser.ParseFilter(string, IEdmType, IEdmEntitySet) – (see <a href="http://blogs.msdn.com/b/alexj/archive/2012/12/06/parsing-filter-and-orderby-using-the-odatauriparser.aspx">this post</a>)</em></span></li>      <li>Parse <strong>$orderby</strong> clause<em> <span style="color: rgb(128, 128, 128);">– Use ODataPathParser.ParseOrderBy(string, IEdmType, IEdmEntitySet) – (see <a href="http://blogs.msdn.com/b/alexj/archive/2012/12/06/parsing-filter-and-orderby-using-the-odatauriparser.aspx">this post</a>)</span></em></li>      <li>Parse <strong>$select</strong> and <strong>$expand</strong> clauses <span style="color: rgb(128, 128, 128);">– </span><span style="color: rgb(0, 0, 255);">(see below)</span></li>      <li>Parse <strong>$inlinecount</strong> clause <span style="color: rgb(128, 128, 128);"><em>– Use ODataPathParser.ParseInlineCount(string)</em></span></li>      <li>Parse <strong>$top</strong> and <strong>$skip</strong> clauses <span style="color: rgb(128, 128, 128);"><em>– Trivial since these are just whole numbers</em></span></li>   </ol> </ol>  <p>If you do this you can build a structure that holds the whole URI converted into various ASTs. In 5.6 we will add a new Parse(..) method that will do this for you and return an appropriate data structure to hold the ODataPath and various query clauses.</p>  <p>In the meantime lets take a look what we’ve added in 5.5:</p>  <h2>Parsing the Path</h2>  <p>This API is pretty simple, you need an <strong>ODataUriParser</strong> (which requires an IEdmModel and a base Uri) then you call ParsePath(..), like this:</p>  <p><span style="color: rgb(0, 0, 255); font-family: consolas;"><span style="color: rgb(0, 128, 0);">// Get a model, clearly you could do this in many ways, in this example we borrow one of the sample OData models</span>       <br />IEdmModel model = EdmxReader.Parse(XmlTextReader.Create(“http://services.odata.org/V3/OData/OData.svc/$metadata”));</span></p>  <p><span style="color: rgb(0, 0, 255); font-family: consolas;"><span style="color: rgb(0, 128, 0);">// Construct a parser for that model</span>       <br />ODataUriParser parser = new ODataUriParser(model, new Uri(“http://server/service”));       <br />      <br /><span style="color: rgb(0, 128, 0);">// Parse a relative path</span>       <br />ODataPath path = parser.ParsePath(new Uri(&quot;http://services.odata.org/V3/OData/OData.svc/Products/ODataDemo.FeaturedProduct(1)/Advertisement&quot;));</span></p>  <p>If you do this you get an <strong>ODataPath</strong> that hold an enumeration of segments.     <br />In this case the segments will be (from first to last):</p>  <table style="width: 584px;" cellspacing="0" cellpadding="2" border="1"><tbody>     <tr>       <td valign="top" width="200"><strong>EntitySetSegment</strong></td>        <td valign="top" width="382">With:          <br />          <br />- An <strong>EdmType</strong> property that returns an <strong>IEdmType</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(an IEdmCollectionType containing a IEdmTypeReference to the ‘ODataDemo.Product’ entity type).</span></em>           <br />- An <strong>EntitySet</strong> property that returns an <strong>IEdmEntitySet</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(in this case ‘Products’).</span></em>           <br />- A convenient <strong>ElementType</strong> property that return an <strong>IEdmEntityType</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(in this case ‘ODataDemo.Product’)</span></em> </td>     </tr>      <tr>       <td valign="top" width="200"><strong>TypeSegment</strong></td>        <td valign="top" width="382">With:&#160; <br />          <br />- An <strong>EdmType</strong> property that returns an <strong>IEdmType</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(in this case an IEdmCollectionType containing an IEdmTypeReference to the ‘ODataDemo.FeaturedProduct’ entity type).</span></em>           <br />- A <strong>Set</strong> property that returns an <strong>IEdmEntitySet</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(in this case ‘Products’)</span></em>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br /></td>     </tr>      <tr>       <td valign="top" width="200"><strong>KeySegment</strong></td>        <td valign="top" width="382">With:          <br />          <br />- An <strong>EdmType</strong> property that returns an <strong>IEdmType</strong> <em><span style="color: rgb(128, 128, 128);">             <br />(in this case the ‘ODataDemo.FeaturedProduct’ entity type).</span></em>           <br />- An <strong>EntitySet</strong> property that returns an <strong>IEdmEntitySet</strong>           <br /><span style="color: rgb(128, 128, 128);"><em>(in this case ‘Products’).</em> </span>          <br />- A <strong>Keys</strong> property that holds a<strong> IEnumerable&lt;KeyValuePair&lt;string,object&gt;&gt;</strong>, where the key is the name of the Entity’s key property and the value is the Entity’s key value.           <br /><em><span style="color: rgb(128, 128, 128);">(in this case 1).</span></em> </td>     </tr>      <tr>       <td valign="top" width="200"><strong>NavigationPropertySegment</strong></td>        <td valign="top" width="382">With:          <br />          <br />- An <strong>EdmType</strong> property that returns an <strong>IEdmType</strong>           <br /><em><span style="color: rgb(128, 128, 128);">(in this case the ‘ODataDemo.Advertisement’ entity type).</span></em>           <br />- An <strong>EntitySet</strong> property that returns an <strong>IEdmEntitySet</strong>           <br /><span style="color: rgb(128, 128, 128);"><em>(in this case ‘Advertisements’).</em></span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />- A <strong>NavigationProperty</strong> property that holds an <strong>IEdmNavigationProperty</strong>           <br /><span style="color: rgb(128, 128, 128);"><em>(in this case ‘Advertisement’).</em></span> </td>     </tr>   </tbody></table>  <p>There are of course other segments OData paths you will encounter other segments like: <strong>PropertySegment</strong>, <strong>BatchSegment</strong>, <strong>MetadataSegment</strong>, <strong>ValueSegment</strong>, <strong>CountSegment</strong>, <strong>NavigationPropertyLinkSegment</strong>, <strong>OperationSegment</strong> and so forth.</p>  <h3>Doesn’t WebAPI have an ODataPath too?</h3>  <p>Those of you using WebAPI will be aware that it has it’s own code for parsing the path part of an OData URI. This is basically just bad timing, if we’d finished the ODataLib URI parser sooner Web API would have used it to parse paths as well. Indeed going forward Web API is likely to refactor their ODataPath code so that it uses the new ODataLib path parsing capabilities.</p>  <h2>Parsing $select and $expand</h2>  <p>The $select and $expand clauses are related, for example $select effects what is expanded. So we have a single method for parsing both simultaneously, this allows us to create an AST that captures the semantics of both query options together.</p>  <p>For example if someone issued a query like this:</p>  <p><span style="font-family: consolas; font-size: small;">GET </span><span style="font-family: consolas; font-size: small;">http://server/service/Products?$select=ID,Name,Category&amp;$expand=Category</span></p>  <p>You would convert this into an AST by making the following calls:</p>  <p><span style="color: rgb(0, 0, 255); font-family: consolas;"><span style="color: rgb(0, 128, 0);">// Construct a parser for that model</span>       <br />ODataUriParser parser = new ODataUriParser(model, new Uri(“http://server/service”)); </span></p>  <p><span style="font-family: consolas;"><span style="color: rgb(0, 128, 0);">// Parse the $select and $expand clauses</span>       <br /><span style="color: rgb(0, 0, 255);">SelectExpandClause selectAndExpand = parser.ParseSelectAndExpand(&quot;ID,Name,Category&quot;, &quot;Category&quot;, type, set);</span></span></p>  <p>The <strong>SelectExpandClause</strong> is a data structure that looks like this:</p>  <table style="width: 570px;" cellspacing="0" cellpadding="2" border="1"><tbody>     <tr>       <td valign="top" width="95"><strong>SelectExpandClause</strong></td>        <td valign="top" width="473">Has a <strong>SelectedItems</strong> property that returns <strong>IEnumerable&lt;SelectItem&gt;</strong>indicating which Properties, NavigationProperties, Actions and Functions have been requested.           <br />          <br />Has a <strong>AllSelected</strong> boolean property that when true means everything is selected at this level. This avoids needing to populate <strong>SelectedItems</strong> with every possible item.</td>     </tr>      <tr>       <td valign="top" width="95"><strong>SelectItem</strong></td>        <td valign="top" width="473">Is an abstract base class. At runtime a <strong>SelectItem</strong> will be one of&#160; <strong>PathSelectItem</strong>, <strong>ExpandedNavigationSelectItem</strong> or <strong>WildcardSelectItem</strong></td>     </tr>      <tr>       <td valign="top" width="95"><strong>PathSelectItem</strong></td>        <td valign="top" width="473">Has a <strong>SelectedPath</strong> property holding an <strong>ODataPath</strong> that terminates with one of <strong>PropertySegment</strong>, <strong>NavigationPropertySegment</strong>, <strong>OpenPropertySegment</strong> or <strong>OperationSegment</strong>.</td>     </tr>      <tr>       <td valign="top" width="95"><strong>ExpandedNavigationSelectItem</strong></td>        <td valign="top" width="473">Has a <strong>PathToNavigationProperty</strong> property that returns a <strong>ODataPath</strong> that terminates with a <strong>NavigationPropertySegment</strong> to indicate which <strong>NavigationProperty</strong> needs to be expanded.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />It also has a <strong>SelectExpandOption</strong> property that returns a nested <strong>SelectExpandClause</strong>. This is where nested selection and expansion information will be stored.           <br />          <br />For example if someone selects “Category/ID” and expands “Category” the nested <strong>SelectExpandClause</strong> for the “Category” <strong>ExpandItem</strong> will have <strong>AllSelected</strong> set to false and the <strong>SelectedItems</strong> will include a <strong>PathSelectItem</strong> for the “ID” property of the “Category”.           <br />          <br />The <strong>ExpandedNavigationSelectItem </strong>is also designed to support V4 of the OData protocol, which allows for filtering, sorting and paging of expanded items. However in V3 these properties will be null.</td>     </tr>      <tr>       <td valign="top" width="95"><strong>WildcardSelectItem</strong></td>        <td valign="top" width="473">Indicates that the client wishes to select every property.</td>     </tr>   </tbody></table>&#160;&#160;&#160;&#160;&#160; <h2>Summary:</h2>  <p>The new version of the <strong>ODataUriParser</strong> that ships in ODataLib version 5.5 is finished. 5.5 adds support for parsing Paths, $select and $expand, which means the ODataUriParser now handles all of OData. All that remains is to add a more convenient way of parsing a full Url in one step, and we will ship something that does that in version 5.6. In the meantime you can still parse an OData Uri completely if you use the algorithm outlined above.</p>  <p>If you have any questions, concerns or suggestion, as always we are keen to hear from you.</p>  <p><strong>-</strong><a href="https://twitter.com/adjames"><strong>Alex</strong></a></p>]]></content:encoded>
    </item>
    <item>
      <title>OData in WebAPI – RC release</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/odata-in-webapi-rc-release</link>
      <pubDate>Fri, 07 Dec 2012 13:38:24 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/12/07/odata-in-webapi-rc-release/</guid>
      <description><![CDATA[Next week we will release an official RC of the Microsoft ASP.NET WebAPI OData assembly. This marks...]]></description>
      <content:encoded><![CDATA[<p>Next week we will release an official RC of the Microsoft ASP.NET WebAPI OData assembly. This marks the third release on our way to RTM.&#160; <br />Although this post talks about code that hasn’t been officially release yet, since all development is happening in public, if you can’t wait till next week, you can always go and get one of the <a href="http://aspnetwebstack.codeplex.com/wikipage?title=Use%20Nightly%20Builds">nightly builds</a> or for a more bare metal experience build it yourself from our <a href="http://aspnetwebstack.codeplex.com/">code repository</a>.</p>  <p>In this post I will cover what is new since the Alpha, if you need a more complete view of what we is currently supported I recommend you read about the <a href="http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx">August Release</a> and the <a href="http://blogs.msdn.com/b/alexj/archive/2012/11/02/odata-in-webapi-microsoft-asp-net-web-api-odata-0-2-0-alpha-release.aspx">Alpha release</a> as well.</p>  <h1>Simplified OData support</h1>  <li>To make it easy to support full OData we’ve added a simple extension method <font face="Consolas">HttpConfiguration.EnableOData(IEdmModel)</font> that allows you to easily configure your service to support OData, simply by providing an <font face="Consolas">IEdmModel</font> and optionally supplying an OData route prefix (i.e. ~/api or similar). </li>  <li></li>  <li>The method does a number of key tasks for you, each of which you can do manually if necessary:</li>  <ul>   <li>Registers an OData wild card route. Which will have a prefix if you specified a prefix when you called <font face="Consolas">EnableOData(..)</font>. For example this:</li>    <ul>     <li><font face="Consolas">HttpConfiguration.EnableOData(model, “api”)</font> will position your OData service under the <font face="Consolas">~/api</font> url prefix.</li>   </ul>    <li>Registers the various <font face="Consolas">ODataMediaTypeFormatters</font>. </li>    <ul>     <li>Note today this will stomp on application/json for your whole service. By RTM we aim to make this much more selective, so you get the OData version of application/json only if your request addresses an OData resource.</li>   </ul>    <li>Stashes the <font face="Consolas">IEdmModel</font> on the configuration</li>    <li>Stashes the <font face="Consolas">DefaultODataPathHandler</font> on the configuration. </li>    <li>Registers the <font face="Consolas">ODataControllerSelector</font> and <font face="Consolas">ODataActionSelectors </font>and configures them to use default OData routing conventions. These selectors only do OData routing when the request is recognized as an OData request, otherwise they delegate to the previously registered selectors.</li> </ul>  <h1>First class OData routing</h1>  <p>In the alpha release to get everything (OData Actions, OData casts, OData navigations etc) working together I updated the <a href="http://aspnet.codeplex.com/SourceControl/changeset/view/17baf56823e7#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt">sample</a> to do custom routing. This routing was based on a component that understood OData Paths and dispatched to actions based on custom routing conventions. At the time we knew this was a merely a stop gap. </p>  <p>That code has now been refactored, improved and moved into the core code base.</p>  <p>The code consists of:</p>  <ul>   <li>A class called <font face="Consolas">ODataPath</font> that represents the path part of an OData Url. An <font face="Consolas">ODataPath</font> is made up of a list of <font face="Consolas">ODataPathSegments</font>, these semantically represent the OData operations you compose to address a resource. For example something like this: <font face="Consolas">~/Customers(10)/Orders</font>, semantically has 3 instructions that are encoded as <font face="Consolas">ODataPathSegments </font>in an <font face="Consolas">ODataPath</font>:</li>    <ul>     <li>Start in the Customers EntitySet</li>      <li>Then find a single customer with the key 10</li>      <li>Then Navigate to the related Orders. </li>   </ul>    <li>An interface called <font face="Consolas">IODataPathHandler</font> that has two methods:</li>    <ul>     <li><font face="Consolas">ODataPath Parse(string odataPath)</font> –&gt; to take a Url and parse it into an <font face="Consolas">ODataPath</font></li>      <li><font face="Consolas">string Link(ODataPath)</font> –&gt; to take an <font face="Consolas">ODataPath </font>and generate a Url.</li>   </ul>    <li>A default implementation of <font face="Consolas">IODataPathHandler</font> called <font face="Consolas">DefaultODataPathHandler</font>, that implements these methods using the OData V3’s built-in conventions. </li>    <li>A way to register and retrieve a <font face="Consolas">IODataPathHandler</font> on your <font face="Consolas">HttpConfiguration</font>. Two things worth calling out here:</li>    <ul>     <li>Normally you don’t have to worry about this, because calling <font face="Consolas">HttpConfiguration.EnableOData(…)</font> registers the <font face="Consolas">DefaultODataPathHandler </font>for you.</li>      <li>This design means that you don’t like the way OData puts keys in parenthesis (i.e.<font face="Consolas">~/Customers(1)</font>) and would prefer to put keys in their own segments (i.e. <font face="Consolas">~/Customer/1</font>) then all you need to do is override the <font face="Consolas">DefaultODataPathHandler </font>so that it recognizes this syntax. I’ve tried this personally and doing targeted overloads like this is pretty easy.</li>   </ul>    <li>All OData link generation conventions (for example for EditLinks or links to invoke actions) now build an <font face="Consolas">ODataPath </font>to represent the link and then ask the registered <font face="Consolas">IODataPathHandler</font> to convert that to a url using the <font face="Consolas">IODataPathHandler.Link(..)</font> method.</li>    <li>An <font face="Consolas">ODataControllerSelector</font> and an <font face="Consolas">ODataActionSelector</font> that route OData requests based on a configurable set of <font face="Consolas">IODataRoutingConventions</font>. Out the box <font face="Consolas">EnableOData(..)</font> will register these routing conventions:</li>    <ul>     <li><font face="Consolas">EntitySetRoutingConvention</font> –&gt; for routing request to manipulate and query an EntitySet, for example:</li>      <ul>       <li><font face="Consolas">GET ~/Customers</font></li>        <li><font face="Consolas">GET ~/Customers/Namespace.VIP</font></li>        <li><font face="Consolas">POST ~/Customers</font></li>     </ul>      <li><font face="Consolas">EntityRoutingConvention</font> –&gt; for routing request to retrieve or manipulate an Entity, for example:</li>      <ul>       <li><font face="Consolas">GET ~/Customer(1)</font></li>        <li><font face="Consolas">GET ~/Customers(1)/Namespace.VIP</font></li>        <li><font face="Consolas">PUT ~/Customer(1)</font></li>        <li><font face="Consolas">PATCH ~/Customers(1)</font></li>        <li><font face="Consolas">DELETE ~/Customers(1)</font></li>     </ul>      <li><font face="Consolas">NavigationRoutingConvention</font> –&gt; for routing requests to retrieve related items, for example:</li>      <ul>       <li><font face="Consolas">GET ~/Customers(1)/Orders</font></li>        <li><font face="Consolas">GET ~/Customers(1)/Namespace.VIP/Benefits</font></li>     </ul>      <li><font face="Consolas">MetadataRoutingConvention</font> –&gt; for routing request to retrieve $metadata or the service document</li>      <ul>       <li><font face="Consolas">GET ~/$metadata</font></li>        <li><font face="Consolas">GET ~</font></li>     </ul>      <li><font face="Consolas">LinksRoutingConvention</font> –&gt; for routing requests to manipulate relationship, for example:</li>      <ul>       <li><font face="Consolas">DELETE ~/Customers(1)/$links/Orders(1)</font></li>        <li><font face="Consolas">POST ~/Customers(1)/$links/Orders</font></li>        <li><font face="Consolas">PUT ~/Customers(1)/$links/RelationshipManager</font></li>     </ul>      <li><font face="Consolas">ActionRoutingConvention</font> –&gt; for routing requests to invoke an OData Action</li>      <ul>       <li><font face="Consolas">POST ~/Customers(1)/ConvertToVIP</font></li>     </ul>      <li><font face="Consolas">UnmappedRequestRoutingConvention</font> –&gt; for routing requests that match no other convention to a fall back method, for example:</li>      <ul>       <li><font face="Consolas">GET ~/Customers(1)/RelationshipManager/Customers</font></li>        <li><font face="Consolas">POST ~/Customers(1)/Orders</font></li>     </ul>   </ul>    <li>A new <font face="Consolas">ODataPathRouteConstraint</font> class that implements <font face="Consolas">IHttpRouteConstraint</font> an makes sure the ‘wildcard route’ that captures every request against your OData service only matches if the Url is in fact an OData url.</li>    <li>An <font face="Consolas">EntitySetController&lt;TEntity,TKey&gt;</font> class that provides a convenient starting point for creating controllers for your OData EntitySets. This class provides stub methods that follow the default <font face="Consolas">IODataRoutingConventions</font> will route requests too. Your job is simply to handle the request. </li> </ul>  <p>For a complete example of how to use all this new goodness check out the sample OData service which you can find at <a href="http://aspnet.codeplex.com">http://aspnet.codeplex.com</a> in the source tree under:&#160; <font face="Consolas">/Samples/Net4/CS/WebApi/ODataService</font>.</p>  <h1>Query validation</h1>  <p>One of the most exciting new features is the ability to specify validation rules to be applied to a query. Essentially this allows you to constrain what query options you allow against your <font face="Consolas">[Queryable]</font>. Under the hood this is all implemented via the virtual <font face="Consolas">ODataQueryOptions.Validate(ODataValidationSettings)</font> method, which you can use if you need to. </p>  <p>That said the 90-99% scenario is simply to specify additional parameters to the <font face="Consolas">[Queryable]</font> attribute that the control what is allowed in a query, and then before the query is processed, Web API converts those settings into an <font face="Consolas">ODataValidationSettings</font> object and calls <font face="Consolas">ODataQueryOptions.Validate(..)</font>. If anything not supported is found in the AST a validation error results, and your backend <font face="Consolas">Queryable</font> never gets called.</p>  <p>Here are some examples:</p>  <p><code><font face="Consolas">[Queryable(AllowedQueryParameters = ODataQueryParameters.Skip| ODataQueryParameters.Top)]</font> </code></p>  <p>This means only Skip and Top are allowed, i.e. a $filter or $orderby would result in a validation error. By default every thing is allowed, until you mention a particular setting, then only the things you list are supported.</p>  <p>Another example is:</p>  <p><code><font face="Consolas">[Queryable(AllowedLogicalOperators=ODataLogicalOperators.Equal)]</font> </code></p>  <p>This says the $filter only supports the Equal operator, so for example this:</p>  <p><font face="Consolas">~/Customer?$filter=Name eq ‘Bob’</font></p>  <p>will pass validation but this:</p>  <p><font face="Consolas">~/Customers?$filter=Name ne ‘Bob’</font></p>  <p>will fail.</p>  <p>Checkout the new <font face="Consolas">[Queryable]</font> attribute to find out more.</p>  <h1>Delta&lt;T&gt; improvements</h1>  <p>This now supports patching classes that derive from the T too. This is useful if you want both these requests:</p>  <p><font face="Consolas">PATCH ~/Customers(1)</font></p>  <p><font face="Consolas">PATCH ~/Customers(1)/Namespace.VIP</font></p>  <p>to be dispatched to the same method, for example:</p>  <p><font color="#0000ff" face="Consolas">public virtual HttpResponseMessage Patch([FromODataUri] TKey key, Delta&lt;Customer&gt; patch)      <br />{       <br />&#160;&#160; …      <br />}</font>    <br />    <br />Now because <font face="Consolas">Delta&lt;Customer&gt;</font> can also hold changes made to a <font face="Consolas">VIP</font> (i.e. a class the derives from <font face="Consolas">Customer</font>) you can route to the same method, and deal with a whole inheritance hierarchy in one action.</p>  <p>Another thing to notice is the new <font face="Consolas">[FromODataUri]</font> attribute, this tells Web API the key parameter is in the URL encoded as an OData Uri Literal.</p>  <h1>$filter improvements</h1>  <p>We now handle <font face="Consolas">DateTime</font> or <font face="Consolas">DateTimeOffset</font> literals or properties for the first time, and we allow you to specify casts in your filter too, for example:</p>  <p><font face="Consolas">~/Customers?$filter=Name eq ‘Bob’ or Namespace.VIP/RelationshipManager/Name eq ‘Bob’</font></p>  <p>At this point the only thing that we don’t support (and won’t support for RTM either) is spatial types and custom OData functions inside the filter. These will come later when support for them is added to ODataLib’s<a href="http://www.nuget.org/packages/Microsoft.Data.OData/5.2.0-rc1"> <font face="Consolas">ODataUriParser</font></a>.</p>  <h1>Partial support for OData’s new JSON format</h1>  <p>This release also includes a little support for the new OData v3 json format, and of course by RTM time we will have full support. This OData V3 json format is more efficient than our older V1/V2 json format (which incidentally the OData team has started calling ‘JSON verbose’, to make sure you know we don’t like it any more :)</p>  <p>The new JSON format has sub types, which allow clients to specify how much metadata they want, ranging from FullMetadata, through MinimalMetadata to NoMetadata. The RC supports the new OData JSON format only for write scenarios (i.e. responding to requests), it doesn’t currently handle read scenarios at all (i.e. request payloads that are in the new JSON format). It supports the most common payload kinds, feeds, entries, errors and service documents, and by RTM we will flesh this out to include other payloads like properties, links etc.</p>  <p>In the RC we don’t support NoMetadata at all, and we treat MinimalMetadata as if it is FullMetadata. We do this because MinimalMetadata means only send metadata and links that the client can’t deduce them by convention, and in the RC we don’t have anyway to tell the formatter that you are indeed following conventions. This forces us to always emit links. By RTM we will add a way to say you are following convention, and that will allow us to support MinimalMetadata properly.</p>  <p>Read <a href="http://www.bitwhys.com/odata-101-what-is-json-light/">What is JSON Light</a> and <a href="http://www.bitwhys.com/odata-101-enabling-json-light-from-the-wcf-ds-5-1-0-rc1-client/">Enabling JSON Light from WCF DS</a> to learn more about the new OData JSON format. </p>  <h1>Summary</h1>  <p>As you can see we’ve been really busy making Web API a first class stack for creating and exposing OData services, ranging from supporting just the OData query syntax, through supporting the majority of the OData protocol, all the way up to supporting extra things not in OData but enabled by Web API, like for example new formats. </p>  <p>As always please let us know what you think.</p>  <p>-<a href="https://twitter.com/adjames"><strong>Alex</strong></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Parsing $filter and $orderby using the ODataUriParser</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/parsing-filter-and-orderby-using-the-odatauriparser</link>
      <pubDate>Thu, 06 Dec 2012 11:50:32 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/12/06/parsing-filter-and-orderby-using-the-odatauriparser/</guid>
      <description><![CDATA[Background and Plans  For a while now we’ve been shipping an early pre-release version of an...]]></description>
      <content:encoded><![CDATA[<h2>Background and Plans</h2>  <p>For a while now we’ve been shipping an early pre-release version of an ODataUriParser in <a href="http://www.nuget.org/packages/Microsoft.Data.OData.Contrib">ODataLib Contrib</a>. The idea is to have code that converts a Uri used to interact with an OData Service into a Semantically bound Abstract Syntax Tree (AST) which represents the request in terms of the OData concepts used.</p>  <p>The ODataUriParser is currently an alpha at best, with many known functionality gaps and bugs. However the <a href="http://aspnetwebstack.codeplex.com/">ASP.NET Web API OData library</a> has a dependency on the parser and is RTMing soon, so we need to bring the quality up quickly.</p>  <p>Our plan is to move Uri Parser out of ODataLib Contrib into a fully supported <a href="http://www.nuget.org/packages/Microsoft.Data.OData">ODataLib</a> release.</p>  <p>Currently ASP.NET Web API only needs support for parsing $filter and $orderby: because today Web API doesn’t support $select and $expand, has it’s own parser for the PATH part of the Uri and all the other OData query options which are very simple to parse. This scoped set of requirements and tight time constraints means the ODataUriParser support we ship in ODataLib will initially be a subset, albeit a better tested and more complete subset, of the ODataUriParser currently in ODataLib Contrib.</p>  <p>So what will the API look like?</p>  <h2>Parsing $filter</h2>  <p>To parse a $filter you need at least two things: an IEdmModel, and an IEdmType to use as your collection element type. Optionally you can provide an IEdmEntitySet too.</p>  <p>For example imagine this request:</p>  <p><u>GET /Service/Customers?$filter=Name eq ‘ACME’</u></p>  <p>To parse the $filter query option, you would need an IEdmModel for the service hosted at ~/Service, and you need to provide the element type of the collection being filtered, in this case Customer. </p>  <p>To create the model, you can use EdmLib code directly:</p>  <p><font color="#0000ff" face="Consolas">var model= new EdmModel();</font></p>  <p><font color="#0000ff" face="Consolas">var customer = new EdmEntityType(&quot;TestModel&quot;, &quot;Customer&quot;);      <br />bool isNullable = false;       <br />var idProperty = customer.AddStructuralProperty(&quot;Id&quot;, EdmCoreModel.Instance.GetInt32(isNullable);       <br />customer.AddKeys(idProperty);       <br />customer.AddStructuralProperty(&quot;Name&quot;, EdmCoreModel.Instance.GetString(isNullable));       <br />edmModel.AddElement(customer);</font></p>  <p><font color="#0000ff" face="Consolas">var container= new EdmEntityContainer(&quot;TestModel&quot;, &quot;DefaultContainer&quot;);      <br />container.AddEntitySet(“Customers”, customer);       <br />model.AddElement(container);</font></p>  <p>This code, builds a model with a single EntityType called customer (with Id and Name properties) an exposes customer instances via an EntitySet called Customers in the default container. Working with EdmLib directly like this, is however quite low-level, another simpler option is to use the <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5b4f63fa0b89#src%2fSystem.Web.Http.OData%2fOData%2fBuilder%2fODataConventionModelBuilder.cs">ODataConventionModelBuilder</a> from the Web API OData package, which provide a nice higher level API for building models. If you go the WebAPI route, be sure to checkout these blog posts: </p>  <ul>   <li><a href="http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx">OData Support in ASP.NET Web API (August 2012)</a></li>    <li><a href="http://blogs.msdn.com/b/alexj/archive/2012/11/02/odata-in-webapi-microsoft-asp-net-web-api-odata-0-2-0-alpha-release.aspx">OData in Web API – Microsoft ASP.NET Web API OData 0.2.0-alpha release (November 2012)</a></li> </ul>  <p>In the above example working out the type of the collection is pretty simple, but of course OData paths (i.e. the bit before the ?) can be quite complicated. To help in the long run this functionality will be provided by the Uri Parser, but for now you have to work this out for the OData Uri Parser. That said, you are not alone, the WebAPI team had the same problem and has create a class called the&#160; <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5b4f63fa0b89#src%2fSystem.Web.Http.OData%2fOData%2fRouting%2fDefaultODataPathParser.cs">DefaultODataPathParser</a> that will work out the type (and EntitySet if appropriate) of any OData path.</p>  <p>Once you have the IEdmModel and IEdmType you need, you can parse the $filter like this:</p>  <p><font color="#0000ff" face="Consolas">FilterNode filter = ODataUriParser.ParseFilter(“Name eq ‘ACME’”, model, customer);</font></p>  <p>If you start exploring this filter which is an AST, you will notice it looks like this:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/4300.QueryTree_13C1E23C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/4300.QueryTree_5F00_13C1E23C.png"><img title="QueryTree" style="border: 0px currentcolor; display: inline;" border="0" alt="QueryTree" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/5861.QueryTree_thumb_0CA2A5C4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/5861.QueryTree_5F00_thumb_5F00_0CA2A5C4.png" width="640" height="266" /></a> </p>  <p>You could easily visit this to produce some sort alternate query syntax, perhaps SQL or CLR expressions. In fact this is what the ASP.NET Web API does, to support the [Queryable] attribute, it first parses the $filter and then it converts the AST into a LINQ expression. You don’t need to do this though, you could for example convert from this AST directly to SQL, which is very useful if you don’t have a LINQ provider, because creating a LINQ provider is a significant undertaking.</p>  <h2>Parsing $OrderBy</h2>  <p>To parse a $orderby you again need an IEdmModel and an IEdmType for the element type of the collection you want to order. For example:</p>  <p>To handle this:</p>  <p><u>GET /Service/Customers?$orderby=Name desc,Id</u></p>  <p>Which orders first by Name descending and then by Id ascending, you would make this call:</p>  <p><font color="#0000ff" face="Consolas">OrderByNode orderby = ODataUriParser.ParseOrderBy(“Name desc, Id”, model, customer);</font></p>  <p>Again if you visit you will see something like this:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/0488.OrderByTree_6C879906.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/0488.OrderByTree_5F00_6C879906.png"><img title="OrderByTree" style="border: 0px currentcolor; display: inline;" border="0" alt="OrderByTree" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/1050.OrderByTree_thumb_1355AF47.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/1050.OrderByTree_5F00_thumb_5F00_1355AF47.png" width="640" height="311" /></a> </p>  <p>If you are familiar with ASTs this will seem pretty simple.</p>  <h2>The Node type hierarchy</h2>  <p>The root of the type hierarchy is <strong>QueryNode</strong>. Beyond that the node hierarchy has been organized to prioritize two key pieces of information, namely:</p>  <ol>   <li>Whether the node represents a Collection or a Single value</li>    <li>Whether the node represents an Entity or another type.</li> </ol>  <p>The first level down from the root of the type hierarchy indicates whether you are dealing with a Single value (<strong>SingleValueNode</strong>) or a Collection (<strong>CollectionNode</strong>). Then the second level down is used to distinguish between Entities and other types, so for example there is a node called <strong>SingleEntityNode</strong> that derives from <strong>SingleValueNode</strong> and a <strong>EntityCollectionNode</strong> that derives from <strong>CollectionNode.</strong></p>  <p>Then the most derived node types distinguish between the various ways of getting to a Collection or Single instance of an Entity or Nonentity. For example the various ways you can get a single entity, one possible way is by following a navigation property with target multiplicity of 0..1 or 1 (<strong>SingleNavigationNode</strong>), and so on, each of these ways are represented as nodes that derive from <strong>SingleEntityNode</strong>. </p>  <p>This approach yields a hierarchy that (when simplified) looks a little like this:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/8816.NodeHierarchy_5E492016.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/8816.NodeHierarchy_5F00_5E492016.png"><img title="NodeHierarchy" style="border: 0px currentcolor; display: inline;" border="0" alt="NodeHierarchy" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/93/87/metablogapi/6763.NodeHierarchy_thumb_3E2E1359.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-93-87-metablogapi/6763.NodeHierarchy_5F00_thumb_5F00_3E2E1359.png" width="640" height="282" /></a> </p>  <p>Amongst the leaf nodes, a few deserve a special mention:</p>  <ul>   <li><strong>BinaryOperatorNode</strong> which represents a Binary operator like for example:&#160; <strong>Name eq ‘Bob’</strong>&#160;</li>    <li><strong>UnaryOperatorNode</strong> which represents a Unary operator like for example: <strong>not True</strong>&#160;</li>    <li><strong>AnyNode</strong> which represents OData any filter expression, for example: collection/<strong>any(a: a/Age gt 100)</strong></li>    <li><strong>AllNode</strong> which represents an OData all filter expression, for example: collection/<strong>all(a: a/Age gt 10)</strong></li> </ul>  <p>From a type system perspective these all represent a boolean value, so then all derive from the natural place in the type hierarchy <strong>SingleValueNode</strong>.</p>  <p>To help recognize which kind of node you are dealing with at any time, all nodes have a <strong>Kind</strong> property which in the RC return one of the constants defined on the static <strong>QueryNodeKind</strong> class. For example if you given a <strong>QueryNode</strong> and you want to write a visitor, you should visit the appropriate derived nodes, first by checking the <strong>QueryNode.Kind</strong> and then casting as appropriate. For RTM we’ll convert Kind to an Enum.</p>  <p>All nodes are held in the Expressions held by classes like FilterClause and OrderByClause, In the future new classes will be introduced to support ODataPath, $select, $expand, etc. Then finally we’ll add a class to represent the full url once we have full coverage of OData urls.</p>  <h2>Conclusion</h2>  <p>The ODataUriParser is on the road to RTM quality now, but it is not happening in one big step, we will start with $filter and $orderby and overtime cover the rest of OData including paths, $expand and $select.</p>  <p>If you are interested in the latest code I invite you to try out the latest version of <a href="http://www.nuget.org/packages/Microsoft.Data.OData">ODataLib</a>.</p>  <p>-Alex</p>]]></content:encoded>
    </item>
    <item>
      <title>OData in WebAPI – Microsoft ASP.NET Web API OData 0.2.0-alpha release</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/odata-in-webapi-microsoft-asp-net-web-api-odata-0-2-0-alpha-release</link>
      <pubDate>Fri, 02 Nov 2012 08:55:31 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/11/02/odata-in-webapi-microsoft-asp-net-web-api-odata-0-2-0-alpha-release/</guid>
      <description><![CDATA[Since my last set of blog posts on OData support in WebAPI (see parts 1 &amp; 2) we’ve been busy...]]></description>
      <content:encoded><![CDATA[<p>Since my last set of blog posts on OData support in WebAPI (see parts <a href="http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx">1</a> &amp; <a href="http://blogs.msdn.com/b/alexj/archive/2012/08/21/web-api-queryable-current-support-and-tentative-roadmap.aspx">2</a>) we’ve been busy adding support for Server Driven Paging, Inheritance and OData Actions. <a href="http://nuget.org/packages/Microsoft.AspNet.WebApi.OData/0.2.0-alpha">Our latest alpha release on Nuget</a> has preview level support for these features. Lets explore the new features and a series of extensions you can use to get them working…</p>  <h2>Server Driven Paging:</h2>  <p>Our code has supported client initiated paging using $skip and $top for some time now. However there are situations where the server wants to initiate paging. For example if a naïve (or potentially malicious) client makes a request like this:</p>  <p><strong><font face="Consolas">GET ~/Products</font></strong></p>  <p>and you have a lot of products, you are supposed to return all the products (potentially thousands, millions, billions) to the client. This uses a lot of computing resources, and this single request ties up all those resources. This is unfortunate because your client:</p>  <ul>   <li>Might simply be malicious</li>    <li>Might be naïve, perhaps it only needed 20 results?</li>    <li>Might lockup waiting for all the products to come over the wire.</li>    <li>etc.</li> </ul>  <p>Thankfully OData has a way to initiate what we call server driven paging, this allows the server to return just a ‘page’ of results + a next link, which tells the client how to retrieve the next page of data. This means naïve clients only get the first page of data and servers have the opportunity to throttle requests from potentially malicious clients because to get all the data multiple requests are required.</p>  <p>This is now really easy to turn on in WebAPI using the Queryable attribute, like this:</p>  <p><font color="#0000ff" size="2" face="Consolas">[Queryable(ResultLimit=100)]     <br />public IQueryable&lt;Product&gt; Get()      <br />{      <br />&#160;&#160; …      <br />}</font></p>  <p>This code, tells WebAPI to return the first 100 matching results, and then add an OData next-link to the results that when followed will re-enter the same method and continue retrieving the next 100 matching results. This process continues until either the client stops following next-links or there is no more data.</p>  <p>If the strategy [Queryable] uses for Server Driven Paging is not appropriate for your data source, you can also drop down and use ODataQueryOptions and ODataResult&lt;T&gt; directly.</p>  <h2>Inheritance:</h2>  <p>The OData protocol supports entity type inheritance, so one entity type can derive from another, and often you’ll want to setup inheritance in your service model. To support OData inheritance we have:</p>  <ul>   <li>Improved the ModelBuilder – you can explicitly define inheritance relationships or you can let the ODataConventionModelBuilder infer them for you automatically.</li>    <li>Improved our formatters so we can serialize and deserialize derived types.</li>    <li>Improved our link generation to include needed casts.</li>    <li>and we need to improve our controller action selection so needed casts are routed correctly.&#160; </li> </ul>  <h3>Model Builder API</h3>  <p>You can explicitly define inheritance relationships, with either the ODataModelBuilder or the ODataConventionModelBuilder, like this:</p>  <p><font face="Con"><code><font color="#008000">// define the Car type that inherits from Vehicle</font></code>       <br /><font color="#0000ff"><code>modelBuilder </code>        <br /><code>.Entity&lt;Car&gt;() </code>        <br /></font><code><font color="#0000ff">.DerivesFrom&lt;Vehicle&gt;()          <br />.Property(c =&gt; c.SeatingCapacity);</font></code></font><font face="Con"><code>&#160;</code></font><code><font face="COn">        <br /></font></code><font face="COn">     <br /></font><font face="Con"><code><font color="#008000">// define the Motorcycle type</font>         <br /></code><font color="#0000ff"><code>modelBuilder </code>        <br /></font><code><font color="#0000ff">.Entity&lt;Motorcycle&gt;()          <br />.DerivesFrom&lt;Vehicle&gt;()           <br />.Property(m =&gt; m.CanDoAWheelie);</font></code></font></p>  <p>With inheritance it occasionally makes sense to mark entity types as abstract, which you can do like this:</p>  <p><font color="#0000ff"><code>modelBuilder </code>      <br /><code>.Entity&lt;Vehicle&gt;() </code>      <br /><code>.Abstract() </code>      <br /></font><code><font color="#0000ff">.HasKey(v =&gt; v.ID)        <br />.Property(v =&gt; v.WheelCount);</font></code><code>&#160;</code></p>  <p>Here we are telling the model builder that Vehicle is an abstract entity type. </p>  <p>When working with derived types you can explicitly define properties and relationship on derived types just as before using EntityTypeConfiguration&lt;TDerivedType&gt;.Property(..), EntityTypeConfiguration&lt;TDerivedType&gt;.HasRequired(…) etc.</p>  <p><strong><font color="#808080">Note:</font></strong><font color="#808080"> <em>In OData every entity type must have a key, either declared or inherited, whether it is abstract or not.</em></font></p>  <h3>ODataConventionModelBuilder and inheritance</h3>  <p>The ODataConventionModelBuilder, which is generally recommended over the ODataModelBuilder, will automatically infer inheritance hierarchies in the absence of explicit configuration. Then once the hierarchy is inferred, it will also infer properties and navigation properties too. This allows you to write less code, focusing on where you deviate from our conventions.&#160;&#160; <br />    <br />For example this code:</p>  <p><font color="#0000ff" size="2" face="Consolas">ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();      <br />modelBuilder.EntitySet&lt;Vehicle&gt;(“Vehicle”);</font></p>  <p>Will look for classes derived from Vehicle and go ahead and create corresponding entity types. </p>  <p>Sometimes you don’t want to have entity types for every .NET type, this is easy to achieve you instruct the model builder to ignore types like this:</p>  <p><font face="Consolas"><font color="#0000ff"><code>builder.IgnoreTypes(</code><code>typeof</code></font></font><code><font color="#0000ff" face="Consolas">(Sportbike));</font> </code></p>  <p>With this code in place the implicit model discovery will not add an entity type for Sportbike, even though it derives from Vehicle (in this case indirectly i.e. Sportbike –&gt; Motorcycle –&gt; Vehicle).</p>  <h3>Known inheritance issues</h3>  <p>In this alpha our support for Inheritance is not quite complete. You can create a service with inheritance in it but there are a number of issues we plan to resolve by RTM:</p>  <ul>   <li>Delta&lt;T&gt;doesn’t currently support derived types. This means issuing PATCH requests against instances of a derived type is not currently working.</li>    <li>Type filtering in the path is not currently supported. <em><font color="#008000">i.e. ~/Vehicles/<strong>NS.Motorcycles</strong>?$filter=…</font></em></li>    <li>Type casts in $filter is not currently supported. <em><font color="#008000">i.e. ~/Vehicles?$filter=<strong>NS.Motorcyles</strong>/Manufacturer/Name eq ‘Ducati’</font></em></li>    <li>Type casts in $orderby is not currently supported. i<font color="#008000"><em>.e. ~/Vehicles?$filter=Name, <strong>NS.Motorcycle</strong>/Manufacturer/Name</em></font></li> </ul>  <ul></ul>  <h2>OData Actions:</h2>  <p>The other major addition since the august preview is support for <a href="http://www.odata.org/blog/2011/10/7/actions-in-odata">OData Actions</a>. Quoting the OData blog:</p>  <p><em>“Actions … provide a way to inject behaviors into an otherwise data centric model without confusing the data aspects of the model, while still staying true to the resource oriented underpinnings of OData.&quot;</em></p>  <p>Adding OData actions support to the WebAPI involves 4 things: </p>  <ol>   <li>Defining OData Actions in the model builder.</li>    <li>Advertising bindable and available actions in representations of the entity sent to clients.</li>    <li>Deserializing parameters values when people attempt to invoke an Action.</li>    <li>Routing requests to invoke OData Actions to an appropriate controller action.</li> </ol>  <ol></ol>  <h3>Model Builder API</h3>  <p>Firstly we added a new class called ActionConfiguration. You can construct this directly if necessary, but generally you use factory methods that simplify configuring the most common kinds of OData Actions, namely those that bind to an Entity or a collection of Entities. For example:</p>  <p><font color="#0000ff" face="Consolas">ActionConfiguration pullWheelie = builder.Entity&lt;Motorcycle&gt;().Action(“PullWheelie”);      <br />pullWheelie.Parameter&lt;int&gt;(“ForSeconds”);       <br />pullWheelie.Returns&lt;bool&gt;();</font></p>  <p>defines an Action called ‘PullWheelie’ that binds to a Motorcycle, and that takes an integer parameter “ForSeconds” indicating how long to hold the wheelie, and returns true/false indicating whether the wheelie was successful.</p>  <p>You can also define an action that binds to a Collection of entities like this:</p>  <p><font color="#0000ff" face="Consolas">ActionConfiguration pullWheelie = builder.Entity&lt;Motorcycle&gt;().Collection.Action(“PullWheelie”);</font></p>  <p>Calling this action would result in a collection of Motorcycles all attempting to ‘Pull a Wheelie’ at the same time :)</p>  <p>There is currently no code in the ODataConventionModelBuilder to infer OData Actions, so actions have to be explicitly added for now. That might change as we formalize our conventions more, but if that happens it won’t be until after the first RTM release.</p>  <h4>Controlling Action links and availability</h4>  <p>When serializing an entity with Actions the OData serializer calls the delegate you pass to ActionConfiguration.HasActionLink(…) for each action. This delegate is responsible for returning a Uri to be embedded in the response sent to the client. The Uri when present tells clients how to invoke the OData Action bound to the current entity. Basically this is <a href="http://en.wikipedia.org/wiki/Hypermedia">hypermedia</a>.</p>  <p>If you are using the ODataConventionModelBuilder, by default the HasActionLink is automatically configured to generate links in the form: <font face="Consolas"><strong>~/entityset(key)[/cast]/action</strong></font>, or for example:</p>  <p><font color="#0000ff" face="Consolas">~/Vehicles(1)/Drive</font></p>  <p>or to access an action bound to a derived type like Motorcyles:</p>  <p><font color="#0000ff" face="Consolas">~/Vehicles(1)/Namespace.Motorcycle/PullWheelie</font></p>  <p>OData also allows you define actions that are only occasionally bindable. For example you might not be able to ‘Stop’ a Virtual Machine if it has already been stopped. This makes ‘Stop’ a transient action. Use the TransientAction() method, which like Action hangs off EntityTypeConfiguration&lt;T&gt;, to define your transient actions. </p>  <p>Finally to make your action truly transient you need to pass a delegate to HasActionLink that returns null when the action is in fact not available.</p>  <h3>Handing requests to invoke ODataActions</h3>  <p>The OData specification says that OData Actions must be invoked using a POST request, and that parameters to the action (excluding the binding parameter) are passed in the body of post in JSON format. This example shows an implementation of the PullWheelie action that binds to a Motorcycle:</p>  <p><font color="#0000ff" face="Consolas">[HttpPost]      <br />public bool PullWheelieOnMotorcycle(int boundId, ODataActionParameters parameters)       <br />{       <br />&#160;&#160; <font color="#008000">// retrieve the binding parameter, in this case a motorcycle, using the <strong>boundId</strong>.         <br />&#160;&#160; // i.e. POST ~/Vehicles(<strong>boundId</strong>)/Namespace.Motorcycle/PullWheelie</font></font><font color="#0000ff" face="Consolas">      <br />&#160;&#160; Motorcycle motorcycle = _dbContext.Vehicles.OfType&lt;Motorcycle&gt;().SingleOrDefault(m =&gt; m.Id == </font><font color="#0000ff" face="Consolas">boundId);      <br />      <br />&#160;&#160; <font color="#008000">// extract the ForSeconds parameter</font>       <br />&#160;&#160; int numberOfSeconds = (int) parameters[“ForSeconds”];</font></p>  <p><font color="#0000ff" face="Consolas">&#160;&#160; <font color="#008000">// left as an exercise to the reader.</font>       <br />&#160;&#160; DoWheelie(motorcycle, numberOfSeconds);</font></p>  <p><font color="#0000ff" face="Consolas">&#160;&#160; return true;      <br /></font><font color="#0000ff" face="Consolas">}</font></p>  <p>As you can see there is a special class here called ODataActionParameters, this is configured to tell the ODataMediaTypeFormatter to read the POST body as an OData Action invocation payload. The ODataActionParameters class is essentially a dictionary from which you can retrieve the parameters used to invoke the action. In this case you can see we are extracting the ‘ForSeconds’ parameter. Finally because the PullWheelie action was configured to return Bool when we defined it, we simply return Bool and the ODataMediaTypeFormatter takes care of the rest.</p>  <p>The only remaining change is setting up routing to handle Actions, Inheritance, NavigationProperties and all the other OData conventions. Unfortunately this problem is a little too involved for standard WebAPI routing. Which means integrating all these new features is pretty hard. </p>  <p>We realized this and started fleshing something called System.Web.Http.OData.Futures to help out…</p>  <h2>Integrating everything using System.Web.Http.OData.Futures</h2>  <p>While the core of all these new features are complete, getting them to work together is tricky. That makes checking out the <a href="http://aspnet.codeplex.com/SourceControl/changeset/view/24eb37621fac#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt">ODataSampleService</a> (part of <a href="http://aspnet.codeplex.com/">aspnet.codeplex.com</a>) even more important. </p>  <p>The sample service itself is starting to look a lot simpler: you don’t need to worry about setting up complicated routes, registering OData formatters etc. In fact all you need to do is call EnableOData(…) on your configuration, passing in your model:</p>  <p><font face="Consolas"><font color="#008000">// Create your configuration (in this case a selfhost one).</font>       <br /><font color="#0000ff">HttpSelfHostConfiguration configuration = new HttpSelfHostConfiguration(_baseAddress);        <br />configuration.Formatters.Clear();</font> </font></p>  <p><font face="Consolas"><font color="#008000">// Enable OData</font>       <br /><font color="#0000ff">configuration.EnableOData(GetEdmModel());</font>       <br />      <br /><font color="#008000">// Create server</font>       <br /><font color="#0000ff">server = new HttpSelfHostServer(configuration);</font>       <br /></font><font face="Consolas"><font color="#008000">       <br />// Start listening</font>       <br /><font color="#0000ff">server.OpenAsync().Wait();        <br />Console.WriteLine(&quot;Listening on &quot; + _baseAddress);</font></font> </p>  <p>As you can see this is pretty simple.</p>  <p>For a description of how GetEdmModel() works checkout my earlier <a title="http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx" href="http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx">post</a>.</p>  <p>As you can imagine EnableOData(…) is doing quite a bit of magic, it:</p>  <ul>   <li>Registers the ODataMediaTypeFormatter</li>    <li>Registers a wild card route, for matching all incoming OData requests</li>    <li>Registers OData routes for generating links in responses (these will probably disappear by RTM).</li>    <li>Registers custom Controller and Actions selectors that parse the incoming request path and dispatch all well understood OData requests by convention. The Action selector dispatches deeper OData requests (i.e. ~/People(1)/BestFriend/BestFriend) to a ‘catch all method’ called HandleUnmappedRequest(…) which you can override if you want.</li> </ul>  <p>All of this is implemented in System.Web.Http.OData.Futures, which includes:</p>  <ul>   <li><strong>OData Route information.</strong></li>    <li><strong>OData specific Controller and Actions selectors</strong> – These classes help avoid routing conflicts. They are necessary because WebAPI’s built-in routing is not sophisticated enough to handle OData’s context sensitive routing needs.</li>    <li><strong>ODataPathParser and ODataPathSegment</strong> – These classes help our custom selectors establish context and route to Controller actions based on conventions.</li>    <li><strong>EntitySetController&lt;T&gt;</strong> – This class implements the conventions used by our custom selectors, and provides a convenient base class for your controllers when supporting OData.</li> </ul>  <p>System.Web.Http.OData.Futures is currently only at sample quality, but it is basically required to creating OData services today, so we plan on merging it into System.Web.Http.OData for the RTM release.</p>  <h2>OData WebAPI Action Routing Conventions:</h2>  <p>The OData ActionSelector is designed to work best with the EntitySetController&lt;TEntity,TKey&gt; and it relies on a series of routing conventions to dispatch OData requests to Controller Actions. You don’t actually need to use the EntitySetController class, so long as you follow the conventions that the OData ActionSelector uses.</p>  <p>The conventions <strong>currently</strong> defined in Futures and used by the sample are:</p> <font size="4"></font>  <table cellspacing="0" cellpadding="2" width="557" border="1"><tbody>     <tr>       <td valign="top" width="255"><font size="4"><strong>Request</strong></font></td>        <td valign="top" width="300"><font size="4"><strong>Routed to Controller.</strong></font></td>     </tr>      <tr>       <td valign="top" width="255"><strong>QUERY</strong></td>        <td valign="top" width="300">&#160;</td>     </tr>      <tr>       <td valign="top" width="255">         <br />          <br />GET ~/EntitySet</td>        <td valign="top" width="300">[Queryable]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />Get()           <br />&#160;&#160; or&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />Get(ODataQueryOptions)</td>     </tr>      <tr>       <td valign="top" width="255"><strong>CRUD</strong></td>        <td valign="top" width="300">&#160;</td>     </tr>      <tr>       <td valign="top" width="255">POST ~/EntitySet</td>        <td valign="top" width="300">Post(Entity)</td>     </tr>      <tr>       <td valign="top" width="255">GET ~/EntitySet(id)</td>        <td valign="top" width="300">GetById(id)</td>     </tr>      <tr>       <td valign="top" width="255">PUT ~/EntitySet(id)</td>        <td valign="top" width="300">Put(id, Entity)</td>     </tr>      <tr>       <td valign="top" width="255">PATCH ~/EntitySet(id)</td>        <td valign="top" width="300">Patch(id, Delta&lt;Entity&gt;)</td>     </tr>      <tr>       <td valign="top" width="255">DELETE ~/EntitySet(id)</td>        <td valign="top" width="300">Delete(id)</td>     </tr>      <tr>       <td valign="top" width="255"><strong>NAVIGATION</strong></td>        <td valign="top" width="300">&#160;</td>     </tr>      <tr>       <td valign="top" width="255">         <br />          <br />GET ~/EntitySet(id)/NavigationSet</td>        <td valign="top" width="300">[Queryable]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />GetNavigationProperty()           <br />&#160;&#160; or&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />GetNavigationProperty(ODataQueryOptions)</td>     </tr>      <tr>       <td valign="top" width="255">GET ~/EntitySet(id)/NavigationSingle</td>        <td valign="top" width="300">GetNavigationProperty() </td>     </tr>      <tr>       <td valign="top" width="255">         <br />          <br />GET           <br />~/EntitySet(id)/cast/NavigationSet</td>        <td valign="top" width="300">[Queryable]&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />GetNavigationPropertyFromCast()           <br />&#160;&#160; or&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />GetNavigationPropertyFromCast(ODataQueryOptions)</td>     </tr>      <tr>       <td valign="top" width="255">GET          <br />~/EntitySet(id)/cast/NavigationSingle</td>        <td valign="top" width="300">         <br />GetNavigationPropertyFromCast() </td>     </tr>      <tr>       <td valign="top" width="255"><strong>MANIPULATING LINKS</strong></td>        <td valign="top" width="300">&#160;</td>     </tr>      <tr>       <td valign="top" width="255">POST          <br />~/EntitySet(id)/$links/NavigationSet</td>        <td valign="top" width="300">         <br />CreateLink(id, navigationProperty, [FromBody] Uri)</td>     </tr>      <tr>       <td valign="top" width="255">PUT          <br />~/EntitySet(id)/$links/NavigationSingle</td>        <td valign="top" width="300">         <br />CreateLink(id, navigationProperty, [FromBody] Uri)</td>     </tr>      <tr>       <td valign="top" width="255">DELETE          <br />~/EntitySet(id)/$links/NavigationSingle</td>        <td valign="top" width="300">         <br />DeleteLink(id, navigationProperty, [FromBody] Uri)</td>     </tr>      <tr>       <td valign="top" width="255">DELETE          <br />~/EntitySet(id)/$links/NavigationSet(relatedId)</td>        <td valign="top" width="300">         <br />DeleteLink(id, relatedId, navigationProperty)</td>     </tr>      <tr>       <td valign="top" width="255"><strong>ACTIONS</strong></td>        <td valign="top" width="300">&#160;</td>     </tr>      <tr>       <td valign="top" width="255">POST ~/EntitySet(boundId)/Action</td>        <td valign="top" width="300">Action(boundId, ODataActionParameters)</td>     </tr>      <tr>       <td valign="top" width="255">POST ~/EntitySet(boundId)/cast/Action</td>        <td valign="top" width="300">ActionOnCast(boundId, ODataActionParameters)</td>     </tr>   </tbody></table>  <p>These conventions are not complete, in fact by RTM we expect to add a few more, in particular to handle:</p>  <table cellspacing="0" cellpadding="2" width="400" border="1"><tbody>     <tr>       <td valign="top" width="400">GET ~/EntitySet/cast</td>     </tr>      <tr>       <td valign="top" width="400">GET ~/EntitySet(id)/cast</td>     </tr>      <tr>       <td valign="top" width="400">POST ~/Action</td>     </tr>      <tr>       <td valign="top" width="400">POST ~/EntitySet/Action</td>     </tr>   </tbody></table>  <p>We are also experimenting with the idea that anything that doesn’t match one of these conventions will get routed to:</p>  <table cellspacing="0" cellpadding="2" width="506" border="1"><tbody>     <tr>       <td valign="top" width="200">POST, PATCH, PUT, DELETE, GET *</td>        <td valign="top" width="304">HandleUnmappedRequest(ODataPathSegment)</td>     </tr>   </tbody></table>  <p>If we did this you would be able to override the default implementation of this and potentially handle OData requests at arbitrary depths :)</p>  <h2>Summary</h2>  <p>As you can see we’ve made a lot of progress, and our OData support is getting more complete and compelling all the time. We still have a number of things to do before RTM, including bringing the ideas from System.Web.Http.OData.Futures into System.Web.Http.OData, finalizing conventions, enabling <a href="http://www.bitwhys.com/odata-101-what-is-json-light/">JSON light</a>, working on performance and fixing bugs etc. That said I hope you’ll agree that things are taking shape nicely?</p>  <p>As always we are keen to hear what you think, even more so if you've kicked the tires a little!</p>  <p><strong>-Alex</strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Web API [Queryable] current support and tentative roadmap</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/web-api-queryable-current-support-and-tentative-roadmap</link>
      <pubDate>Mon, 20 Aug 2012 17:56:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/08/20/web-api-queryable-current-support-and-tentative-roadmap/</guid>
      <description><![CDATA[The recent preview release of OData support in Web API&nbsp; is very exciting (see the new nuget...]]></description>
      <content:encoded><![CDATA[<p>The recent preview release of OData support in Web API&nbsp; is very exciting (see the <a href="http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData">new nuget package</a> and <a href="http://aspnetwebstack.codeplex.com/">codeplex project</a>). For the most part it is compatible with the previous <strong>[Queryable]</strong> support because it supports the same OData query options. That said there has been a little confusion about how <strong>[Queryable] </strong>works, what it works with and what its limitations are, both temporary and long term.&nbsp;</p>
<p>The rest of this post will outline what is currently supported, what limitations currently exist and which limitations are hopefully just temporary.</p>
<h1>Current Support</h1>
<h2>Support for different ElementTypes</h2>
<p>In the preview the <strong>[Queryable]</strong> attribute works with any <strong>IQueryable&lt;&gt;</strong> or <strong>IEnumerable&lt;&gt;</strong> data source (Entity Framework or otherwise), for which a model has been configured or can be inferred automatically.</p>
<p>Today this means that the element type (i.e. the T in IQueryable&lt;T&gt;) must be viewed as an EDM entity. This implies a few constraints:</p>
<ul>
<li>All properties you wish to expose must be exposed as CLR properties on your class.</li>
<li>A key property (or properties) must be available</li>
<li>The type of all properties must be either:</li>
<ul>
<li>a clr type that is mapped to an EDM primitive, i.e. System.String == Edm.String</li>
<li>Or clr type that is mapped to another type in your model, be that a ComplexType or an EntityType</li>
</ul>
</ul>
<p><br /><span color="#a5a5a5" style="color: #a5a5a5;"><strong>NOTE:</strong> using <strong>IEnumerable&lt;&gt;</strong> is recommended only for small amounts of data, because the options are only applied after everything has been pulled into memory.</span></p>
<h2>Null Propagation</h2>
<p>This feature takes a little explaining, so please bear with me. Imagine you have an action that looks like this:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">[Queryable] <br />public IQueryable&lt;Product&gt; Get() <br />{ <br />&nbsp;&nbsp;&nbsp; &hellip; <br />}</span></p>
<p>Now imagine someone issues this request:</p>
<p><strong><span face="Consolas" style="font-family: Consolas;">GET <span style="text-decoration: underline;">~/Products?$filter=startswith(Category/Name,&rsquo;A&rsquo;)</span></span></strong></p>
<p>You might think the <strong>[Queryable]</strong> attribute will translate the request to something like this: <br /> <br /><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">Get().Where(p =&gt; p.Category.Name.StartsWith(&ldquo;A"));</span></p>
<p>But that might be very bad&hellip; <br />If your Get() method body looks like this:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">return _db.Products; <span color="#a5a5a5" style="color: #a5a5a5;">// i.e. Entity Framework.</span></span></p>
<p>It will work just fine. But if your Get() method looks like this:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">return products.AsQueryable();</span></p>
<p>It means the LINQ provider being used is LINQ to Objects. L2O evaluates the where predicate in memory simply by calling the predicate. Which could easily null ref if either <strong>p.Category</strong> or <strong>p.Category.Name</strong> are null.</p>
<p>The <strong>[Queryable]</strong> attribute handles this automatically by injecting null guards into the code for certain IQueryable Providers. If you dig into the <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/b11acf178a83#src%2fSystem.Web.Http.OData%2fOData%2fQuery%2fODataQueryOptions.cs">code for ODataQueryOptions</a> you&rsquo;ll see this code:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&hellip; <br />string queryProviderAssemblyName = query.Provider.GetType().Assembly.GetName().Name; <br />switch (queryProviderAssemblyName) <br />{ <br />&nbsp;&nbsp;&nbsp; case EntityFrameworkQueryProviderAssemblyName: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handleNullPropagation = false; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; <br />&nbsp;&nbsp;&nbsp; case Linq2SqlQueryProviderAssemblyName: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handleNullPropagation = false; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; <br />&nbsp;&nbsp;&nbsp; case Linq2ObjectsQueryProviderAssemblyName: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handleNullPropagation = true; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; <br />&nbsp;&nbsp;&nbsp; default: <br />&nbsp;&nbsp;&nbsp; handleNullPropagation = true; <br />&nbsp;&nbsp;&nbsp; break; <br />} <br />return ApplyTo(query, handleNullPropagation);</span></p>
<p>As you can see for Entity Framework and LINQ to SQL we don&rsquo;t inject null guards (because SQL takes care of null guards/propagation automatically), but for L2O and all other query providers we inject null guards and propagate nulls. <br /> <br />If you don&rsquo;t like this behavior you can override it by dropping down and calling <strong><span face="Consolas" style="font-family: Consolas;">ODataQueryOptions.Filter.ApplyTo(..)</span></strong> directly.</p>
<h2>Supported Query Options</h2>
<p>In the preview the <strong>[Queryable]</strong> attribute supports only 4 of OData&rsquo;s 8 built-in query options, namely $filter, $orderby, $skip and $top.</p>
<p>What about the 4 other query options? i.e. $select, $expand, $inlinecount and $skiptoken. Today you need to use <strong>ODataQueryOptions</strong> rather than [Queryable], hopefully that will change overtime.</p>
<h2>Dropping down to ODataQueryOptions</h2>
<p>The first thing to understand is that this code:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">[Queryable] <br />public IQueryable&lt;Product&gt; Get() <br />{ <br />&nbsp;&nbsp;&nbsp; return _db.Products; <br /></span><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">} <br /></span> <br />Is roughly equivalent to:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;"></span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">public IEnumerable&lt;Product&gt; Get(ODataQueryOptions options) <br />{ <br />&nbsp;&nbsp;&nbsp; <span color="#008000" style="color: #008000;">// TODO: we should add an override of ApplyTo that avoid all these casts! <br /></span>&nbsp;&nbsp;&nbsp; return options.ApplyTo(_db.Products as IQueryable) as IEnumerable&lt;Product&gt;; <br />}</span></p>
<p>Which in turn is roughly equivalent to:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">public IEnumerable&lt;Product&gt; Get(ODataQueryOptions options) <br />{</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; IQueryable results = _db.Products; <br /><span color="#008000" style="color: #008000;">&nbsp;&nbsp;&nbsp; <span color="#0000ff" style="color: #0000ff;">if (options.Filter != null) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results = options.Filter.ApplyTo(results); <br />&nbsp;&nbsp;&nbsp; if (options.OrderBy != null) </span><span color="#008000" style="color: #008000;">// this is a slight over-simplification see </span><a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/b11acf178a83#src%2fSystem.Web.Http.OData%2fOData%2fQuery%2fODataQueryOptions.cs"><span style="text-decoration: underline;"><span color="#008000" style="color: #008000;">this</span></span></a></span><span color="#0000ff" style="color: #0000ff;"><span color="#008000" style="color: #008000;">. <br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results = options.OrderBy.ApplyTo(results); <br />&nbsp;&nbsp;&nbsp; if (options.Skip != null) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results = options.Skip.ApplyTo(results); <br />&nbsp;&nbsp;&nbsp; if (options.Top != null) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; results = options.Top.ApplyTo(results);</span></span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; return results; <br />}</span></p>
<p>This means you can easily pick and choose which options to support. For example if your service doesn&rsquo;t support <strong>$orderby</strong> you can assert that <strong>ODataQueryOptions.OrderBy</strong> is null.</p>
<h2>ODataQueryOptions.RawValues</h2>
<p>Once you&rsquo;ve dropped down to the&nbsp; <strong>ODataQueryOptions</strong> you also get access to the <strong>RawValues</strong> property which gives you the raw string values of all 8 <strong>ODataQueryOptions</strong>&hellip; So in theory you can handle more query options.</p>
<h2>ODataQueryOptions.Filter.QueryNode</h2>
<p>The ApplyTo method assumes you have an IQueryable, but what if you backend has no IQueryable implementation?</p>
<p>Creating one from scratch is very hard, mainly because LINQ allows so much more than OData allows, and essentially obfuscates the intent of the query. <br />To avoid this complexity we provide <strong>ODataQueryOptions.Filter.QueryNode</strong> which is an AST that gives you a parsed metadata bound tree representing the $filter. The AST of course it tuned to allow only what OData supports, making it much simpler than a LINQ expression.</p>
<p>For example this <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/b11acf178a83#test%2fSystem.Web.Http.OData.Test%2fOData%2fQuery%2fFilterQueryOptionTest.cs">test fragment</a> illustrates the API: <br /> <br /><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">var filter = new FilterQueryOption("Name eq 'MSFT'", context);&nbsp; <br />var node = filter.QueryNode;&nbsp; <br />Assert.Equal(QueryNodeKind.BinaryOperator, node.Expression.Kind);&nbsp; <br />var binaryNode = node.Expression as BinaryOperatorQueryNode;&nbsp; <br /> Assert.Equal(BinaryOperatorKind.Equal, binaryNode.OperatorKind);&nbsp; <br /> Assert.Equal(QueryNodeKind.Constant, binaryNode.Right.Kind);&nbsp; <br /> Assert.Equal("MSFT", ((ConstantQueryNode)binaryNode.Right).Value);&nbsp; <br /> Assert.Equal(QueryNodeKind.PropertyAccess, binaryNode.Left.Kind);&nbsp; <br /> var propertyAccessNode = binaryNode.Left as PropertyAccessQueryNode;&nbsp; <br /> Assert.Equal("Name", propertyAccessNode.Property.Name);</span> </p>
<p>If you are interested in an example that converts one of these ASTs into another language take a look at the <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/b11acf178a83#src%2fSystem.Web.Http.OData%2fOData%2fQuery%2fExpressions%2fFilterBinder.cs">FilterBinder</a> class. This class is used under the hood by <strong>ODataQueryOptions</strong> to convert the Filter AST into a LINQ Expression of the form <strong>Expression&lt;Func&lt;T,bool&gt;&gt;</strong>.</p>
<p>You could do something very similar to convert directly to SQL or whatever query language you need. Let me assure you doing this is MUCH easier than implementing IQueryable!</p>
<h2>ODataQueryOptions.OrderBy.QueryNode</h2>
<p>Likewise you can interrogate the <strong>ODataQueryOptions.OrderBy.Query</strong> for an AST representing the <strong>$orderby</strong> query option.</p>
<h1>Possible Roadmap?</h1>
<p>These are just ideas at this stage, really we want to hear what you want, that said, here is what we&rsquo;ve been thinking about:</p>
<h2>Support for $select and $expand</h2>
<p>We hope to add support for both of these both as <strong>QueryNodes</strong> (like Filter and OrderBy), and natively by the <strong>[Queryable]</strong> attribute.</p>
<p>But first we need to work through some issues:</p>
<ul>
<li>The OData Uri Parser (part of ODataContrib) currently doesn&rsquo;t support $select / $expand, and we need that first.</li>
<li>Both <strong>$expand</strong> and <strong>$select</strong> essentially change the shape of the response. For example you are still returning <strong>IQueryable&lt;T&gt;</strong> from your action but:</li>
<ul>
<li>Each T might have properties that are not loaded. How would the formatter know which properties are not loaded?</li>
<li>Each T might have relationships loaded, but simply touching an unloaded relationship might cause lazyloading, so the formatters can&rsquo;t simply hit a relationship during serialization as this would perform terribly, they need to know what to try to format.</li>
</ul>
<li>There is no guarantee that you can &lsquo;expand&rsquo; an <strong>IEnumerable</strong> or for that matter an <strong>IQueryable</strong>, so we would need a way to tell <strong>[Queryable]</strong> which options it is free to try to handle automatically. </li>
</ul>
<h2>Support for $inlinecount and $skiptoken</h2>
<p>Again we hope to add support to <strong>[Queryable] </strong>for both of these. <br /> <br />That said today you can implement both of these by returning<strong> ODataResult&lt;&gt;</strong> from your action today. <br />Implementing <strong>$inlinecount </strong>is pretty simple:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">public ODataResult&lt;Product&gt; Get(ODataQueryOptions options)</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">{</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; var results = (options.ApplyTo(_db.Products) as IQueryable&lt;Product&gt;);</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; var count = results.Count; </span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; var limitedResults = results.Take(100).ToArray();</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">&nbsp;&nbsp;&nbsp; return new ODataResult&lt;Product&gt;(results,null,count);</span></p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">}</span></p>
<p>&nbsp;</p>
<p>However implementing server driven paging (i.e. <strong>$skiptoken</strong>) is more involved and easy to get wrong.&nbsp; <br /> I&rsquo;ll blog about how to do Server Driven Pages pretty soon.</p>
<h2>Support for more Element Types.</h2>
<p>We want to support both Complex Types (Complex Type are just like entities, except they don&rsquo;t have a key and have no relationships) and primitive element types. For example both:</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">public IQueryable&lt;string&gt; Get();</span>&nbsp;<span color="#a5a5a5" style="color: #a5a5a5;">&ndash; maps to say <span face="Consolas" style="font-family: Consolas;"><strong>GET <span style="text-decoration: underline;">~/Tags</span></strong></span></span></p>
<p>and</p>
<p><span color="#0000ff" face="Consolas" style="color: #0000ff; font-family: Consolas;">public IQueryable&lt;Address&gt; Get(parentId);</span>&nbsp;<span color="#a5a5a5" style="color: #a5a5a5;">&ndash; maps to say <span face="Consolas" style="font-family: Consolas;"><strong>GET <span style="text-decoration: underline;">~/Person(6)/Addresses</span></strong></span></span></p>
<p>where no key property has been configured or can be inferred for Address.</p>
<p>You might be asking yourself how do you query a collection of primitives using OData? Well in OData you use the <strong>$it</strong> implicit iteration variable like this:</p>
<p><strong><span face="Consolas" style="font-family: Consolas;">GET <span style="text-decoration: underline;">~/Tags?$filter=startswith($it,&rsquo;A&rsquo;)</span></span></strong></p>
<p>Which gets all the Tags that start with &lsquo;A&rsquo;.</p>
<h2>Virtual Properties and Open Types</h2>
<p>Essentially virtual properties are things you want to expose as properties via your service that have no corresponding clr property. A good example might be where you to use methods to get and set a property value. This one is a little further out, but it is clearly useful.</p>
<h1>Conclusion</h1>
<p>As you can see <strong>[Queryable]</strong> is a work in progress that is layered above <strong>ODataQueryOptions</strong>, we are planning to improve both over time, and we have a number of ideas. But as always we&rsquo;d love to hear what you think!</p>]]></content:encoded>
    </item>
    <item>
      <title>OData support in ASP.NET Web API</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/odata-support-in-asp-net-web-api</link>
      <pubDate>Wed, 15 Aug 2012 14:46:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/08/15/odata-support-in-asp-net-web-api/</guid>
      <description><![CDATA[UPDATE 2&nbsp;@1:21 pm on 16th August (PST): There is an updated version of the nuget package that...]]></description>
      <content:encoded><![CDATA[<p><span style="color: #666666;" color="#666666"><em><strong>UPDATE 2&nbsp;@1:21 pm on 16th August (PST):</strong> <br />There is an <a href="http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData/0.1.0-alpha-120815">updated version of the nuget package</a> that resolves the previous dependency issues. Oh and my comments are now working again.</em></span></p>
<p><span style="color: #666666;" color="#666666"><em><strong>UPDATE 1 @10:00 am on 16th August (PST):</strong> <br />If you&rsquo;ve tried using the preview nuget package and had problems, rest assured we are working on the issue (which is a dependency version issue). Essentially the preview and one of its dependencies have conflicting dependencies on specific versions of packages. The ETA for a fix that resolves this nuget issue is later today.&nbsp; <br />Also if you&rsquo;ve made a comment and it isn&rsquo;t showing up, don&rsquo;t worry it will. I&rsquo;m currently having technical problems approving comments.</em></span></p>
<p>Earlier versions <a href="http://www.asp.net/web-api">ASP.NET Web API</a> included basic support for the <a href="http://www.odata.org">OData</a>, allowing you to use the OData Query Options $filter, $orderby, $top and $skip to shape the results of controller actions annotated with the <strong>[Queryable]</strong> attribute. This was very useful and worked across formats. That said true support for the OData format was rather limited.&nbsp; In fact we barely scratched the surface of OData, for example there was no support for creates, updates, deletes, $metadata and code generation etc.</p>
<p>To address this we&rsquo;ve create a preview of a <a href="http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData">new nuget package</a> (and <a href="http://aspnetwebstack.codeplex.com/">codeplex project</a>) for building OData services that:</p>
<ul>
<li>Continues to support the [Queryable] attribute, but also allows you to drop down to an Abstract Syntax Tree (or AST) representing $filter &amp; $orderby.</li>
<li>Adds ways to infer a model by convention or explicitly customize a model that will be familiar to anyone who&rsquo;s used Entity Framework Code First.</li>
<li>Adds support for service documents and $metadata so you can generate clients (in .NET, Windows Phone, Metro etc) for your Web API.</li>
<li>Adds support for creating, updating, partially updating and deleting entities.</li>
<li>Adds support for querying and manipulating relationships between entities.</li>
<li>Adds the ability to create relationship links that wire up to your routes.</li>
<li>Adds support for complex types.</li>
<li>Adds support for Any/All in $filter.</li>
<li>Adds the ability to control null propagation if needed (for example to avoid null refs working about LINQ to Objects).</li>
<li>Refactors everything to build upon the same foundation as <a href="http://msdn.microsoft.com/en-us/data/odata.aspx">WCF Data Services</a>, namely ODataLib.</li>
</ul>
<p><br />In fact this is an early preview of a new OData Server stack built to take advantage of Web APIs inherent flexibility and power which compliments WCF Data Services.</p>
<p>This preview ships with a <a href="http://aspnet.codeplex.com/SourceControl/changeset/view/903afc4e11df#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt">companion OData sample service</a> built using Web API. The sample includes three controllers, that each expose an OData EntitySet with varying capabilities. One is rudimentary supporting just query and create, the other two are more complete, supporting Query, Create, Update, Patch, Delete and Relationships. The first complete example does everything by hand, the second derives from a sample base controller called EntitySetController that takes care of a lot of the plumbing for you and allows you to focus on the business logic.</p>
<p>The rest of this blog post will introduce you to the components that make up this preview and how to stitch them together to create an OData service, using the code from <a href="http://aspnet.codeplex.com/SourceControl/changeset/view/903afc4e11df#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt">this sample</a> from the <a href="http://aspnet.codeplex.com/">ASP.NET Web Stack Sample repository</a> if you want to follow along.</p>
<h1>[Queryable] aka supporting OData Query</h1>
<p>If you want to support OData Query options, without necessarily supporting the OData Formats, all you need to do it put the [Queryable] attribute on an action that returns either IQueryable&lt;&gt; or IEnumerable&lt;&gt;, like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">[Queryable] <br />public IQueryable&lt;Supplier&gt; GetSuppliers() <br />{ <br />&nbsp;&nbsp;&nbsp; return _db.Suppliers; <br />}</span></p>
<p>Here _db is an EntityFramework DBContext. If this action is routed to say ~/Suppliers then any OData Query options applied to that URI will be applied by an Action Filter before the result is sent to the client.</p>
<p>For example this: ~/Suppliers?$filter=Name eq &lsquo;Microsoft&rsquo;</p>
<p>Will pass the result of <span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">GetSuppliers().Where(s =&gt; s.Name == &ldquo;Microsoft&rdquo;)</span> to the formatter.</p>
<p>This all works as it did in earlier previews, although there are a couple of, hopefully temporary, caveats:</p>
<ul>
<li>The element type can&rsquo;t be primitive (for example IQueryable&lt;string&gt;).</li>
<li>Somehow the [Queryable] attribute must find a key property. This happens automatically if your element type has an ID property, if not you might need to manually configure the model (see setting up your model).</li>
</ul>
<h1>Doing more OData</h1>
<p>If you want to support more of OData, for example, the official OData formats or allow for more than just reads, you need to configure a few things.</p>
<p>The <a href="http://aspnet.codeplex.com/SourceControl/changeset/view/903afc4e11df#Samples%2fNet4%2fCS%2fWebApi%2fODataServiceSample%2fReadMe.txt">ODataService.Sample</a> shows all of this working end to end, and the remainder of this post will talk you through what that code is doing.</p>
<h2>Setting up your model</h2>
<p>The first thing you need is a model. The way you do this is very similar to the Entity Framework Code First approach, but with a few OData specific tweaks:</p>
<ul>
<li>The ability to configure how EditLinks, SelfLinks and Ids are generated.</li>
<li>The ability to configure how links to related entities are generated.</li>
<li>Support for multiple entity sets with the same type.</li>
</ul>
<p><br />If you use the ODataConventionModelBuilder most of this is done automatically for you, all you need to do is tell the builder what sets you want, for example this code:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); <br />modelBuilder.EntitySet&lt;Product&gt;("Products"); <br />modelBuilder.EntitySet&lt;ProductFamily&gt;("ProductFamilies"); <br />modelBuilder.EntitySet&lt;Supplier&gt;("Suppliers"); <br />IEdmModel model = modelBuilder.GetEdmModel();</span></p>
<p>Builds a model with 3 EntitySets (Products, ProductFamilies and Suppliers) where the EntityTypes of those sets are inferred from the CLR types (Product, ProductFamily and Supplier) automatically, and where EditLinks, SelfLinks and IdLinks are all configured to use the default OData routes.</p>
<p>You can also take full control of the model by using the ODataModelBuilder class, here you explicitly add EntityTypes, Properties, Keys, NavigationProperties and how to route Links by hand. For example this code:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">var products = modelBuilder.EntitySet&lt;Product&gt;("Products"); <br />products.HasEditLink(entityContext =&gt; entityContext.UrlHelper.Link(&nbsp; <br />&nbsp;&nbsp;&nbsp; ODataRouteNames.GetById,&nbsp; <br />&nbsp;&nbsp;&nbsp; new { controller = "Products", id = entityContext.EntityInstance.ID }&nbsp; <br />)); <br /></span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">var product = products.EntityType; <br />product.HasKey(p =&gt; p.ID); <br />product.Property(p =&gt; p.Name); <br />product.Property(p =&gt; p.ReleaseDate); <br />product.Property(p =&gt; p.SupportedUntil);</span></p>
<p>Explicitly adds a EntitySet called Products to the model, configures the EditLink (and unless overridden the SelfLink and IdLink) generation so that if uses the ODataRouteNames.GetById route, and then as you can see the code needed to configure the Key and Properties is very similar to the Code First.</p>
<p>For a more complete example take a look at the GetExplicitEdmModel() method in the sample it builds the exact same model as the ODataConventionModelBuilding by hand.</p>
<h2>Setting up the formatters, routes and built-in controllers</h2>
<p>To use the OData formats you first need to register an ODataMediaTypeFormatter, which will need the model you built previously:</p>
<p><span style="font-family: Consolas;" face="Consolas"><span style="color: #008000;" color="#008000">// Create the OData formatter and give it the model <br /></span><span style="color: #0000ff;" color="#0000ff">ODataMediaTypeFormatter odataFormatter = new ODataMediaTypeFormatter(model);</span></span></p>
<p><span style="font-family: Consolas;" face="Consolas"><span style="color: #008000;" color="#008000">// Register the OData formatter</span> <br /><span style="color: #0000ff;" color="#0000ff">configuration.Formatters.Insert(0, odataFormatter);</span></span></p>
<p>Next you need to setup some routes to handle common OData requests, below are the routes required for a Read/Write OData model built using the OData Routing conventions that also supports client side code-generation (vital if you want a WCF DS client application to talk to your service).</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas"><span style="color: #9bbb59;" color="#9bbb59"><span style="color: #008000;" color="#008000">// Metadata routes to support $metadata and code generation in the WCF Data Service client.</span> <br /></span>configuration.Routes.MapHttpRoute( <br />&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">ODataRouteNames.Metadata, <br />&nbsp;&nbsp;&nbsp; "$metadata", <br />&nbsp;&nbsp;&nbsp; new { Controller = "ODataMetadata", Action = "GetMetadata" } <br />); <br />configuration.Routes.MapHttpRoute( <br />&nbsp;&nbsp;&nbsp; ODataRouteNames.ServiceDocument, <br />&nbsp;&nbsp;&nbsp; "", <br />&nbsp;&nbsp;&nbsp; new { Controller = "ODataMetadata", Action = "GetServiceDocument" } <br />);</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas"><span style="color: #008000;" color="#008000">// Relationship routes (notice the parameters is {type}Id not id, this avoids colliding with GetById(id)). <br />// This code handles requests like ~/ProductFamilies(1)/Products</span> <br />configuration.Routes.MapHttpRoute(ODataRouteNames.PropertyNavigation, "{controller}({parentId})/{navigationProperty}");</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas"><span style="color: #008000;" color="#008000">// Route for manipulating links, the code allows people to create and delete relationships between entities</span> <br />configuration.Routes.MapHttpRoute(ODataRouteNames.Link, "{controller}({id})/$links/{navigationProperty}");</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas"><span style="color: #008000;" color="#008000">// Routes for urls both producing and handling urls like ~/Product(1), ~/Products() and ~/Products</span> <br /></span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">configuration.Routes.MapHttpRoute(ODataRouteNames.GetById, "{controller}({id})"); <br />configuration.Routes.MapHttpRoute(ODataRouteNames.DefaultWithParentheses, "{controller}()"); <br />configuration.Routes.MapHttpRoute(ODataRouteNames.Default, "{controller}"); <br /></span> <br />One thing to note is the way that the ODataRouteNames.PropertyNavigation route attempts to handle requests to urls like ~/ProductFamilies(1)/Products and ~/Products(1)/Family etc. Essentially a single route for all Navigations. For this to work without requiring a single Action for all navigation properties, we register a custom action selector that will build the Action name using the {navigationProperty} parameter of the PropertyNavigation route:</p>
<p><span style="font-family: Consolas;" face="Consolas"><span style="color: #008000;" color="#008000">// Register an Action selector that can include template parameters in the name</span> <br /><span style="color: #0000ff;" color="#0000ff">configuration.Services.Replace(typeof(IHttpActionSelector), new ODataActionSelector());</span></span></p>
<p>This custom action selector will dispatch a request to <strong><span style="color: #0000ff;" color="#0000ff">GET</span></strong> ~/ProductFamilies(1)/<strong><span style="text-decoration: underline;">Products</span></strong>, to an action called the <strong><span style="color: #0000ff;" color="#0000ff">Get</span><span style="text-decoration: underline;">Products</span></strong>(int parentId) on the ProductFamilies controller.</p>
<p>At this point our previous GetSupplier action can return OData formats. However it will still produce links that won&rsquo;t work when dereferenced. To fix this we need to start creating our controllers.</p>
<h2>Adding Support for OData requests</h2>
<p>In our model we added 3 entitysets: Products, ProductFamilies and Suppliers. So first we create 3 controllers, called ProductController, ProductFamiliesController and SuppliersController respectively.</p>
<h3>Queries</h3>
<p>By convention your controllers should have a method called Getxxx() that returns IQueryable&lt;T&gt;. Here the T is the CLR type backing your EntitySet, so for example on the ProductsController which is for the Products entityset the T should be Product, and the action should look something like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">[Queryable] <br />public IQueryable&lt;Product&gt; GetProducts() <br />{ <br />&nbsp;&nbsp;&nbsp; return _db.Products; <br />}</span></p>
<p>As you can see this is the same as before, but now it is participating in a &lsquo;compliant&rsquo; OData service. Inside this method you can do all sorts of things, you can add additional filters based on the identity of the caller, you do auditing, you can do logging, you can aggregate data from multiple sources.</p>
<p>There is even a way to drop down a layer so you get to the see the OData query that has been received. Doing this allows you to process the query yourself in whatever way is appropriate for your data sources. For example you might not have an IQueryable you can use. See ODataQueryOptions for more on this.</p>
<p>At this point because you&rsquo;ve registered a model and you&rsquo;ve setup routes for $metadata and the OData Service Document, you should be able to use Visual Studio&rsquo;s Add Service Reference to generate a set of client proxy classes that you could use like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">foreach(var product in ctx.Products.Where(p =&gt; p.Name.StartsWith(&ldquo;MS&rdquo;)) <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(product.Name); <br />}</span></p>
<p>WCF DS client will then translate this into a GET request like this:</p>
<p>~/Products$filter=startswith(Name,&rsquo;MS&rsquo;)</p>
<p>And everything should just work.</p>
<h3>Get by Key</h3>
<p>To retrieve an individual item using it&rsquo;s key in OData you send a GET request to a url like this: ~/Products(1). The ODataRouteNames.GetById route handles requests like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage GetById(int id) <br />{ <br />&nbsp;&nbsp;&nbsp; Supplier supplier = _db.Suppliers.SingleOrDefault(s =&gt; s.ID == id);&nbsp; <br />&nbsp;&nbsp;&nbsp; if (supplier == null)&nbsp; <br />&nbsp;&nbsp;&nbsp; {&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.NotFound);&nbsp; <br />&nbsp;&nbsp;&nbsp; }&nbsp; <br />&nbsp;&nbsp;&nbsp; else&nbsp; <br />&nbsp;&nbsp;&nbsp; {&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.OK, supplier);&nbsp; <br />&nbsp;&nbsp;&nbsp; } <br />}</span></p>
<p>As you can see the code simply attempts to retrieve an item by ID, and then return it with a 200 OK response or return 404 Not Found.</p>
<p>If you have WCF DS proxy classes on the client a request like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">ctx.Products.Where(p =&gt; p.ID == 5).FirstOrDefault();</span></p>
<p>Should now hit this action.</p>
<h3>Inserts (POST requests)</h3>
<p>To create a new Entity in OData you POST a new Entity directly to the url that represents the EntitySet, this means that insert requests just like queries end up matching the ODataRouteNames.Default route, however Web API&rsquo;s action selector picks actions prefixed with Post for POST requests to distinguish from GET requests for Queries:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage PostProduct(Product product) <br />{ <br />&nbsp;&nbsp;&nbsp; product.Family = null;</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; Product addedProduct = _db.Products.Add(product);&nbsp; <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges();&nbsp; <br /> <br />&nbsp;&nbsp;&nbsp; var response = Request.CreateResponse(HttpStatusCode.Created, addedProduct);&nbsp; <br />&nbsp;&nbsp;&nbsp; response.Headers.Location = new Uri( <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">Url.Link(ODataRouteNames.GetById, new { Controller = "Products", Id = addedProduct.ID }) <br />&nbsp;&nbsp;&nbsp; );&nbsp; <br />&nbsp;&nbsp;&nbsp; return response; <br />}</span></p>
<p>Here we simply add the product to our Entity Framework context and then call SaveChanges(). The only interesting bit way we set the location header using the ODataRouteNames.GetById route (i.e. the default OData route for Self/Edit links).</p>
<h3>Updates (PUT requests)</h3>
<p>To replace an Entity in OData you PUT the updated version of the entity to the uri specified in the EditLink of the entity. This will match the GetById route, but because it is a PUT request it will look for an Action name prefixed with Put.</p>
<p>This example shows how to do this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage Put(int id, Product update) <br />{ <br />&nbsp;&nbsp;&nbsp; if (!_db.Products.Any(p =&gt; p.ID == id)) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw ODataErrors.EntityNotFound(Request); <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; update.ID = id; // ignore the ID in the entity use the ID in the URL. <br />&nbsp;&nbsp;&nbsp; _db.Products.Attach(update); <br />&nbsp;&nbsp;&nbsp; _db.Entry(update).State = System.Data.EntityState.Modified; <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges(); <br />&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.NoContent); <br />}</span></p>
<p>The code is pretty simple, first we verify the entity the client is trying to update actually exists, then we ignore the ID in the entity and instead use the id extracted from the uri of the request, this stops clients updating one entity using the editlink of another entity.</p>
<p>Once all that validation is out of the way we attach the updated entity and tell EF it has been modified before calling save changes and finally returning a No Content response.</p>
<p>As you can see this leverages a helper class called ODataErrors, its job is simply to raise OData compliant errors. The sample uses the EntityNotFound method quite frequently, and it follows the general pattern for failing in an OData compliant way so lets take a peak at its implementation:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public static HttpResponseException EntityNotFound(this HttpRequestMessage request) <br />{&nbsp; <br />&nbsp;&nbsp;&nbsp; return new HttpResponseException(&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request.CreateResponse(&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HttpStatusCode.NotFound,&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ODataError&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Message = "The entity was not found.",&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageLanguage = "en-US",&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ErrorCode = "Entity Not Found."&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )&nbsp; <br />&nbsp;&nbsp;&nbsp; ); <br />}</span></p>
<p>We create a HttpResponseException with a nested Not Found response, the body of which contains an ODataError. By putting an ODataError in the body we get the ODataMediaTypeFormatter to format the body as a valid OData error message as per the content-type requested by the client.</p>
<p>NOTE: Over time we will try to teach the ODataMediaTypeFormatter to handle HttpError as well by using a default translation from HttpError to ODataError.</p>
<h3>Partial Updates (PATCH requests)</h3>
<p>PUT request have replace semantics which makes updates all or nothing, meaning you have to send all the properties even if only a subset have changed.This is where PATCH comes in, PATCH allows clients to send just the modified properties on the wire, essentially allowing for partial updates.</p>
<p>This example shows an implementation of Patch for Products:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage PatchProduct(int id, Delta&lt;Product&gt; product) <br />{ <br />&nbsp;&nbsp;&nbsp; Product dbProduct = _db.Products.SingleOrDefault(p =&gt; p.ID == id); <br />&nbsp;&nbsp;&nbsp; if (dbProduct == null) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new HttpResponseException(HttpStatusCode.NotFound); <br />&nbsp;&nbsp;&nbsp; } <br /> <br />&nbsp;&nbsp;&nbsp; product.Patch(dbProduct); <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges();</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.NoContent); <br />}</span></p>
<p>Notice that the method receives a Delta&lt;Product&gt; rather than a Product.</p>
<p>We do this because, if we use a Product directly and set the properties that came on the wire as part of the patch request, we would not be able to tell why a property has a default value. It could be because the request set the property to its default value or it could be because the property hasn&rsquo;t been set yet. This could lead to mistakenly resetting properties the client doesn&rsquo;t want reset. Can anyone say &lsquo;data corruption&rsquo;?</p>
<p>The Delta&lt;Product&gt; class is a dynamic class that acts as a lightweight proxy for a Product. It allows you to set any Product property, but it also remembers which properties you have set. It uses this knowledge when you call .Patch(..) to copy across only properties that have been set.</p>
<p>Given this we simply retrieve the product from the database and then we call Patch to apply the changes requested to the entity in the database. Once that is done we call SaveChanges to push the changes to the database.</p>
<h3>Deletes (DELETE requests)</h3>
<p>To delete an entity you send a DELETE request to it&rsquo;s editlink, so this is similar to GetById, Put and Patch, except this time Web API will look for an action prefixed with Delete, something like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage DeleteProduct(int id) <br />{ <br /></span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; Product toDelete = _db.Products.FirstOrDefault(p =&gt; p.ID == id); <br />&nbsp;&nbsp;&nbsp; if (toDelete == null) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw ODataErrors.EntityNotFound(Request); <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; _db.Products.Remove(toDelete); <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges();</span><span style="color: #0000ff;" color="#0000ff"> <br /><span style="font-family: Consolas;" face="Consolas">&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.Accepted); <br />}</span></span></p>
<p>As you can see if the entity is found it is simply deleted and we return an Acccepted response.</p>
<h3>Following Navigations</h3>
<p>To address related entities in OData you typically start with the Uri of a particular entity and then append the name of the navigationProperty. For example to retrieve the Family for Product 15 you do a GET request here: ~/Products(15)/Family.</p>
<p>Implementing this is pretty simple:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public ProductFamily GetFamily(int parentId) <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp; return _db.Products.Where(p =&gt; p.ID == parentId).Select(p =&gt; p.Family).SingleOrDefault(); <br />}</span></p>
<p>This matches the ODataRouteNames.PropertyNavigation which you&rsquo;ll notices uses {parentId} rather than {id}, if it was id, this method would also be a match for the ODataRouteNames.GetById route, which would cause problems in the action selector infrastructure. By using parentId we sidestep this issue.</p>
<h3>Creating and Deleting links</h3>
<p>The OData protocol allows you to get and modify links between entities as first class resources. In the preview however we only support modifications.</p>
<p>To create links you POST or PUT a uri (specified in the request body) to a url something like this: ~/Products(1)/$links/Family.</p>
<p>The uri in the body points to the resource you wish to assign to the relationship. So in this case it would be the uri of a ProductFamily you wish to assign to Product.Family (i.e. setting Product 1&rsquo;s Family).</p>
<p>Whether you POST or PUT depends on the cardinality of the relationship, if it is a Collection you POST, if it is a single item (as Family is) you PUT. Both are mapped through the ODataRouteNames.Link route, which is set up to handle creating links for any relationship. Unlike following Navigations it feels okay to use a single method because the return type always the same, i.e. a No Content response:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage PutLink(int id, string navigationProperty, [FromBody] Uri link) <br />{ <br />&nbsp;&nbsp;&nbsp; Product product = _db.Products.SingleOrDefault(p =&gt; p.ID == id);</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; switch (navigationProperty) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case "Family": <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The utility method uses routing (ODataRoutes.GetById should match) to get the value of {id} parameter <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // which is the id of the ProductFamily. <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int relatedId = Configuration.GetKeyValue&lt;int&gt;(link); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ProductFamily family = _db.ProductFamilies.SingleOrDefault(f =&gt; f.ID == relatedId); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; product.Family = family; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw ODataErrors.CreatingLinkNotSupported(Request, navigationProperty);&nbsp; <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges();</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.NoContent); <br />}</span></p>
<p>The {navigationProperty} parameter from the route is used to decide what relationship to create, also notice the [FromBody] attribute on the Uri link parameter it is vital otherwise the link will always be null.</p>
<p>If you want to remove a relationship between entities you send a DELETE request to the same URL, the code for that looks like this:</p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">public HttpResponseMessage DeleteLink(int id, string navigationProperty, [FromBody] Uri link) <br />{ <br />&nbsp;&nbsp;&nbsp; Product product = _db.Products.SingleOrDefault(p =&gt; p.ID == id); <br /></span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; switch (navigationProperty) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case "Family": <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; product.Family = null; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</span></p>
<p><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default: <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw ODataErrors.DeletingLinkNotSupported(Request, navigationProperty); <br />&nbsp;&nbsp;&nbsp; } <br />&nbsp;&nbsp;&nbsp; _db.SaveChanges(); <br /></span><span style="color: #0000ff; font-family: Consolas;" color="#0000ff" face="Consolas">&nbsp;&nbsp;&nbsp; return Request.CreateResponse(HttpStatusCode.NoContent); <br />}</span></p>
<h1>Conclusion</h1>
<p>If you implement all these methods for each of your OData EntitySets you should have a compliant OData service. Of course this code is only at preview quality so is likely to have bugs, that said I hope you&rsquo;ll agree this provides a good foundation for creating OData services.</p>
<p>We are currently thinking about adding support for: inheritance, OData actions &amp; functions, etags and JSON Light etc. And of course we want to hear your thoughts so we can incorporate your feedback!</p>
<h2>Next up</h2>
<p>This blog post doesn&rsquo;t cover everything you can do with the Preview, you can use:</p>
<ul>
<li>ODataQueryOptions rather than [Queryable] to take full control of handling the query.</li>
<li>ODataResult&lt;&gt; to implement OData features like Server Driven Paging and $inlinecount.</li>
<li>EntitySetController&lt;,&gt; to simplify creating fully compliant OData entitysets.</li>
</ul>
<p><br />I&rsquo;ll be blogging more about these soon.</p>
<p>Enjoy!</p>]]></content:encoded>
    </item>
    <item>
      <title>CQRS with OData and Actions?</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/cqrs-with-odata-and-actions</link>
      <pubDate>Fri, 03 Feb 2012 15:23:35 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2012/02/03/cqrs-with-odata-and-actions/</guid>
      <description><![CDATA[I love the Actions feature in OData – which is hardly surprising given I was one of its...]]></description>
      <content:encoded><![CDATA[<p>I love the Actions feature in OData – which is hardly surprising given I was one of its designers.&#160; <br />    <br />Here’s the main reason why I love it: Actions allow you move from a CRUD architecture style, where you query and modify data using the same model, to an architectural style where you have a clear separation between the model used to query and the model used to update. To me this feels a lot like <a href="http://codebetter.com/gregyoung/">Greg Young</a>’s baby CQRS, or <a href="http://martinfowler.com/bliki/CQRS.html">Command Query Responsibility Segregation</a>. </p>  <p>I’ll admit I’m taking some liberties here because these two models are actually ‘merged’ into a single metadata document ($metadata) that describes them both, and you can share types between these two models… however this feels insignificant because the key benefits remain.</p>  <p>Why would you want to move from a CRUD style application to a CQRS style one?</p>  <p>Let’s look at a simple scenario, imagine you have Products that look like this:</p>  <p><font color="#0000ff" face="Consolas">public class Product      <br />{       <br />&#160;&#160; public int ID {get;set;}       <br />&#160;&#160; public string Name {get;set;}       <br />&#160;&#160; public Decimal Cost {get;set;}       <br />&#160;&#160; public Decimal Price {get;set;}       <br />}</font></p>  <p>And imagine you want to Discount Marmite (a product in your catalog) by 15%. Today using the CRUD style, the default in OData before Actions, there is only one option: you PUT a new version of the Marmite resource with the new Price to the URL that represents Marmite, i.e. something like this:</p>  <p><font color="#0000ff" face="Consolas">POST ~/Products(15) HTTP/1.1      <br />Content-Type: application/json       <br />      <br />{       <br />&#160;&#160; <font color="#9bbb59">// abbreviated for readability        <br /></font>&#160;&#160; “ID”: 15,       <br />&#160;&#160; “Name”: “Marmite”,       <br />&#160;&#160; “Cost”: 3.50,       <br />&#160;&#160; “Price”: <font color="#ff0000">4.25</font>&#160;&#160;&#160; <font color="#9bbb59">// ($5 – 15%)</font>&#160; <br />}</font></p>  <p>Notice to support this you have to allow PUT for Products. And this has some real issues:</p>  <ul>   <li>People can now make changes that we don’t necessarily want to allow, i.e. modifying the Name &amp; Cost or changing the Price too much.      <ul>       <li>Basically “Update Product” is NOT the same as “Discount Product”. </li>     </ul>   </li>    <li>When a change comes through we don’t actually know it is a Discount. It just looks like an attempt to update a Product. </li>    <li>If you need information that is not part of Product to perform a Discount (perhaps a justification) there is no where to put that information. </li> </ul>  <p>   <br />More generally the CRUD model is painful because:</p>  <ul>   <li>If you want to update lots of resources simultaneously, imagine for example that you want to discount every product in a particular category, you first have to retrieve every product in that category, and then you have to do a PUT for each of them. This of course introduces a lot of unnecessary latency and introduces consistency challenges (it is hard to maintain a transaction boundary across requests &amp; it the longer the ‘transaction’ lasts the more likely a concurrency check will fail). </li>    <li>If you want to update something you have to allow it to be read somewhere. </li> </ul>  <p>   <br />Back to our scenario, it would be much better to disable PUT completely and create a Discount action, and advertise it’s availability in the Marmite resource (to keep your system as Hypermedia driven as possible):</p>  <p><font color="#0000ff" face="Consolas">{      <br />&#160; “__metadata”: {       <br />&#160;&#160;&#160;&#160; // abbreviated for simplicity       <br />&#160;&#160;&#160;&#160; “Actions”: {       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; “#MyActions.Discount”: [{ “title”: “Discount Marmite”, “target”: “Products(15)/Discount”}]       <br />&#160;&#160;&#160;&#160; }       <br />&#160; </font><font color="#0000ff" face="Consolas">},&#160; <br />&#160; “ID”: 15,       <br />&#160; “Name”: “Marmite”,       <br />&#160; “Cost”: 3.50,       <br />&#160; “Price”: 5.00       <br />}</font></p>  <p>The name of the Action (i.e. #MyActions.Discount) is an ‘anchor’ into the metadata document that can be found at ~/$metadata that says you need to provide a percentage.</p>  <p><font color="#0000ff" face="Consolas">POST ~/Products(15)/Discount HTTP/1.1      <br />Content-Type: application/json</font></p>  <p><font color="#0000ff" face="Consolas">{      <br />&#160;&#160;&#160; “percentage”: 15       <br />}</font></p>  <p>This is much better. Notice this doesn’t allow me to modify the Cost or the Name, and indeed can easily be validated to make sure the percentage is within an acceptable range, and it is semantically much clearer what is happening.</p>  <p>In fact by moving from a CRUD style architecture to one inspired by CQRS but based on actions you can:</p>  <ul>   <li>Give targeted update capabilities that:      <ul>       <li>Allow only certain parts of the ‘Read’ model to be modified. </li>        <li>Allow things that are not even in the ‘Read’ model to be modified or provided if needed. </li>     </ul>   </li>    <li>Selectively give users permissions to only the ‘Actions’ or Commands they need. </li>    <li>Log every Action and replay them at a later date to rebuild your data (i.e. Event Sourcing). </li>    <li>Capture what is requested (i.e. Discount the product) and respond immediately before the change has actually been made, safe in the knowledge you will eventually process the request and achieve “Eventual Consistency”. </li>    <li>Capture more information about what is happening (i.e. User X discounted Marmite by 15% is much better than User X updated Marmite). </li>    <li>Create Actions that manipulate a lot of entities simultaneously (i.e. POST ~/Categories(‘Yeast Spreads’)/Products/Discount…) </li> </ul>  <p>   <br />Of course simply separating the read/write models in OData doesn’t give you all of these advantages immediately, but at least it creates a foundation that can scale to support things like Event Sourcing or Eventual Consistency later if required. </p>  <p>Some of you may be thinking you can achieve many of these goals by having a more granular model that makes things like “Discount” a resource, and that would be true. However for most people using OData that way of thinking is foreign and more importantly the EDM foundations of OData get in the way a little too. So for me Actions seems like the right approach in OData.</p>  <p>I love this.    <br />But what do you think?     <br />-<a href="https://twitter.com/adjames">Alex</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Judgment</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/judgment</link>
      <pubDate>Mon, 06 Jun 2011 23:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2011/06/06/judgment/</guid>
      <description><![CDATA[In my last post I blithely said 'This
is where judgment comes in...'. 
Unfortunately judgment...]]></description>
      <content:encoded><![CDATA[<p>In my last post I blithely said '<a href="http://blogs.msdn.com/controlpanel/b/alexj/archive/2011/06/03/how-do-i-do-design.aspx">This
is where judgment comes in...</a>'. </p>
<p>Unfortunately judgment isn't easy.</p>
<p>Now when I was younger - say 10 years ago - I was sure about
everything - not least my latest harebrained API design. I chalk that up to
inexperience and not knowing better.</p>
<p>But now after 15 years of making design mistakes I have a
lot more experience. So much so that I can literally see problems with almost
every design. A big part of this is experience morphing into instinct.</p>
<p>Instinct is very useful because it helps weed out absurd
ideas quickly. But instinct has limits. It is not much use if you are feeling
equally uneasy about 3 possible designs. </p>
<p>You need to realize your instincts are based on all your
experiences, and no one project encompasses all your experiences. Which means you can easily
can fooled into thinking something matters when it really doesn't.</p>
<p>For example if you feel uneasy about one of the possible
solutions because it looks inefficient. It might be your 'performance is important
instinct' kicking in. If you are working on a website expected to get millions
of hits a day, that is a valid concern. But if this is a departmental app with
10 users who each hit the site no more than 10 times a day, then probably not
so much.</p>
<p>I know this performance example is contrived, but believe me
often it won't be so obvious. You need a reliable way to discard irrelevant concerns
and focus on the real issues.</p>
<p>The best way to do this is to have a set of guiding
principles for every project you work on. Things like:</p>
<ul>
<li>Simplicity is a feature</li>
<li>Predictability &amp; Uniformity</li>
<li>Embrace existing standards</li>
<li>Payload Driven (HATEOS)</li>
</ul>
<p>Creating a list like this gives you something more concrete
than instincts to test when you get that uneasy feeling. </p>
<p>If you have an uneasy feeling you simple ask yourself, Does this
violate any of my projects guiding principles? </p>
<p>I generally find that uneasy feelings will vanish or become
showstoppers when you do this.<br />
Enough so that you'll be much more comfortable making a choice...</p>
<p>... perhaps even the right choice!</p>]]></content:encoded>
    </item>
    <item>
      <title>How do I do design?</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/how-do-i-do-design</link>
      <pubDate>Fri, 03 Jun 2011 14:14:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2011/06/03/how-do-i-do-design/</guid>
      <description><![CDATA[For a while now I've been thinking that the best way to get better at API &amp; protocol design is...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small">For a while now I've been thinking that the best way to get better at API &amp; protocol design is to try to articulate how you do design.</span></p>  <p><span style="font-size: small">Articulating your thought process has a number of significant benefits:      <br /></span></p>  <ul>   <li><span style="font-size: small">Once you know your approach you can critique and try to improve it.</span> </li>    <li><span style="font-size: small">Once you know what you'd like to do, in a collaborative setting you can ask others for permission to give it a go. In my experience phrases like <i>&quot;I'd like to explore how this is similar to LINQ ...&quot;</i> work well if you want others to brainstorm with you.</span> </li>    <li><span style="font-size: small">Once you understand what you do perhaps you can teach or mentor.</span> </li>    <li><span style="font-size: small">Or perhaps others can teach you.</span> </li> </ul>  <p><span style="font-size: small">     <br />Clearly these are compelling.</span></p>  <p><span style="font-size: small">So I thought I'd give this a go by trying to document an <em>idealized</em> version of the thought process for Any/All in OData...</span></p>  <h1>The Problem</h1>  <p><span style="font-size: small">OData had no way to allow people to query entities based on properties of a related collection, and a <a href="http://data.uservoice.com/forums/72027-wcf-data-services-feature-suggestions">lot of people</a>, myself included, wanted to change this...</span> </p>  <h1>Step 1: Look for inspiration</h1>  <p><span style="font-size: small">I always look for things that I can borrow ideas from. Pattern matching, if you will, with something proven. Here you are limited only by your experience and imagination, there is an almost limitless supply of inspiration. The broader your experience the more source material you have and the higher the probability you will be able to see a useful pattern. </span></p>  <p><span style="font-size: small"></span><span style="font-size: small">If you need it – and you shouldn’t - this is just another reason to keep learning new languages, paradigms and frameworks! </span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Sometimes there is something obvious you can pattern match with, other times you really have to stretch...</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">In this case the problem is really easy. Our source material is LINQ. LINQ already allows you to write queries like this:</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">from movie in Movies        <br />where movie.Actors.Any(a =&gt; a.Name == 'Zack')         <br />select movie;</span></span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">Which filters movies by the actors (a related collection) in the movie, and that is exactly what we need in OData.</span> </p>  <h1>Step 2: Translate from source material to problem domain</h1>  <p><span style="font-size: small">My next step is generally to take the ideas from the source material and try to translate them to my problem space. As you do this you'll start to notice the differences between source and problem, some insignificant, some troublesome. </span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">This is where judgment comes in, you need to know when to go back to the drawing board. For me I know I'm on thin ice if I start saying things like <i>'well if I ignore X and Y, and imagine that Z is like this'</i> .</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">But don't give up too early either. Often the biggest wins are gained by comparing things that seem quite different until you look a little deeper and find a way to ignore the differences that don't really matter. For example Relational Databases and the web seem very different, until you focus on </span><a href="http://dl.dropbox.com/u/361389/Base4Blog/Post-036.htm"><span style="font-size: small">ForeignKeys vs Hyperlinks</span></a><span style="font-size: small">, pull vs push seems different until you read about </span><a href="https://channel9.msdn.com/Shows/Going+Deep/Bart-De-Smet-Observations-on-IQbservable-The-Dual-of-IQueryable"><span style="font-size: small">IQueryable vs IObservable</span></a><span style="font-size: small">.</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Notice not giving up here is all about having tolerance for ambiguity, the higher your tolerance, the further you can stretch an idea. Which is vital if you want to be really creative. </span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">In the case of Any/All it turns out that the inspiration and problem domain are very similar, and the differences are insignificant.</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">So how do you do the translation? </span></p>  <p><span style="font-size: small">In OData predicate filters are expressed via $filter, so we need to convert this LINQ predicate:</span></p>  <p><span style="color: #0000ff"><span style="font-size: small"><span style="font-family: consolas">(movie) =&gt; movie.Actors.Any(actor =&gt; actor.Name == 'Zack')</span>&#160;</span></span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">into something we can put in an OData $filter. </span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Let's attack this systematically from left to right. In LINQ you need to name the lambda variable in the predicate, i.e. movie, but in OData there is no need to name the thing you are filtering, it is implicit, for example this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">from movie in Movies        <br />where movie.Name == &quot;Donnie Darko&quot;         <br />select movie</span></span></p>  <p><span style="font-size: small">is expressed like this in OData:      <br /></span></p>  <p><span style="font-family: consolas; font-size: small"><span style="color: #0000ff">       <br />~/Movies/?$filter=Name eq 'Donnie Darko'</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Notice there is no variable name, we access the Name of the movie implicitly.</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">So we can skip the ‘movie’.</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Next in LINQ the Any method is a built-in extension method called directly off the collection using '.Any'. In OData '/' is used in place of '.', and built-in methods are all lowercase, so that points are something like this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(????)</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">As mentioned previously in OData we don't name variables, everything is implicit. Which means we can ignore the actor variable. That leaves only the filter, which we can convert using existing LINQ to OData conversion rules, to yield something like this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(Name eq 'Zack')</span></span></p>  <h1>Step 3: Did you lose something important?</h1>  <p><span style="font-size: small">There is a good chance you lost something important in this transformation, so my next step is generally to assess what information has been lost in translation. Paying particular attention to things that are important enough that your source material had specific constructs to capture them.</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">As you notice these differences you either need to convince yourself the differences don’t matter, or you need to add something new to your solution to bring it back.</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">In our case you'll remember that in LINQ the actor being tested in the Any method had a name (i.e. 'actor'), yet in our current OData design it doesn't.</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Is this important?</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">Yes it is! Unlike the root filter, where there is only one variable in scope (i.e. the movie), inside an Any/All there are potentially two variables in scope (i.e. the movie and the actor). And if neither are named we won't be able to distinguish between them!</span></p>  <p><span style="font-size: small"></span><span style="font-size: small">For example this query, which finds any movies with the same name as any actors who star in the movie, is unambiguous in LINQ:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">from movie in Movies        <br />where movie.Actors.Any(actor =&gt; actor.Name == movie.Name)         <br />select movie;</span></span></p>  <p><span style="font-size: small">But our proposed equivalent is clearly nonsensical:</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(Name eq Name)</span></span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">It seems we need a way to refer to both the inner (actor) and outer variables (movie) explicitly. </span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Now we can't change the way existing OData queries work - without breaking clients and servers already deployed - which means we can't explicitly name the outer variable, we can however introduce a way to refer to it implicitly. This should be a reserved name so it can't collide with any properties. OData already uses the $ prefix for reserved names (i.e. $filter, $skip etc) so we could try something like $it . This results in something like this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(Name eq $it/Name)</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">And now the query is unambiguous again.</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">But unfortunately we aren't done yet. We need to make sure nesting works calls works too, for example this:</span></p>  <p><span style="font-size: small"></span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">from movie in Movies        <br />where movie.Actors.Any(actor =&gt; actor.Name == movie.Name &amp;&amp; actor.Awards.Any(award =&gt; award.Name == 'Oscar'))         <br />select movie;</span></span></p>  <p><span style="font-size: small">If we translate this, with the current design we get this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(Name eq $it/Name AND Awards/any(Name eq 'Oscar'))</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">But now it is unclear whether <span style="font-family: consolas">Name eq 'Oscar'</span> refers to the actor or the award. Perhaps we need to be able to name the actor and award variables too. Here we are not restricted by the past, Any/All is new, so it can include a way to explicitly name the variable. Again we look at LINQ for inspiration:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">award =&gt; award.Name == 'Oscar'</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Cleary we need something like '=&gt;' that is URI friendly and compatible with the current OData design. It turns out ':' is a good candidate, because it works well in querystrings, and isn’t currently used by OData, and even better there is a precedent in Python lambda’s (notice the pattern matching again). So the final proposal is something like this:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(actor: actor/Name eq $it/Name)</span></span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Or for the nested scenario:</span><span style="font-size: small">&#160;</span></p>  <p><span style="color: #0000ff"><span style="font-family: consolas; font-size: small">~/Movies/?$filter=Actors/any(actor: actor/Name eq $it/Name AND actor/Awards/any(award: award/Name eq 'Oscar'))</span></span></p>  <p><span style="font-family: segoe; font-size: small">And again nothing is ambiguous.</span></p>  <h1>Step 4: Rinse and Repeat</h1>  <p><span style="font-size: small">In this case the design feels good, so we are done.</span></p>  <p><span style="font-size: small">But clearly that won't always be the case. However you should at least know whether the design is looking promising or not. If not it is back to the drawing board. </span></p>  <p><span style="font-size: small">If it does look promising, I would essentially repeat steps 1-3 again using some other inspiration to inform further tweaking of the design, hopefully to something that feels complete.</span></p>  <h1>Conclusion</h1>  <p><span style="font-size: small">While writing this up I definitely teased out a number of things that had previously been unconscious, and I sure this will help me going forward, hopefully you too? </span></p>  <p><span style="font-size: small"></span></p>  <p><span style="font-size: small">Next time I do this I'll explore something that involves more creativity... and I'll try to tease out more of the unconscious tools I use.</span></p>  <p><span style="font-size: small">What do you think about all this? Do you have any suggested improvements?</span><span style="font-size: small">&#160;</span></p>  <p><span style="font-size: small">-<a href="https://twitter.com/adjames">Alex</a></span></p>]]></content:encoded>
    </item>
    <item>
      <title>TechEd 2010 Videos</title>
      <link>https://docs.microsoft.com/archive/blogs/alexj/teched-2010-videos</link>
      <pubDate>Sat, 12 Jun 2010 09:05:11 GMT</pubDate>
      <dc:creator><![CDATA[Alex D James]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/alexj/2010/06/12/teched-2010-videos/</guid>
      <description><![CDATA[If you didn't get to TechEd - no problem - videos of all the sessions are available here.
Including...]]></description>
      <content:encoded><![CDATA[<p>If you didn't get to TechEd - no problem - videos of all the sessions are available <a href="http://www.msteched.com/">here</a>.</p>
<p>Including my <a href="http://www.msteched.com/2010/NorthAmerica/DEV323">Best Practices: Creating an OData Service using WCF Data Services session</a>.</p>
<p>If you watch that video and want to follow try it out - you can <a href="http://blogs.msdn.com/b/alexj/archive/2010/06/11/odata-wcf-data-services-best-practices-from-teched.aspx">download all the source code I uploaded previously</a>.</p>
<p>Enjoy.</p>]]></content:encoded>
    </item>
  </channel>
</rss>