Telerik blogs

Nowadays, it is more and more common for web developers to utilize RESTfull like services in their projects. There is nothing surprising in that, since in the nature of REST is to provide uniform interface to access the data. One may ask, what uniform means at all? Well simply said, all operations have the same meaning across all the resources they can act on.

OData in turn, is a protocol that exposes your data to the web in a simple, RESTlike manner. A consumer can query the data via set of URL parameters and receive a response in the JSON format, which is native for the web.

Having that in mind, we are happy to announce that forth from Q3 2011 release the navigation controls (for now - RadTreeView, RadMenu, RadListBox, RadComboBox) can be bound to OData services that return JSON feed. After the RadGrid, these are the next portion of controls to support such binding. The binding in turn, can be hierarchical or not. As one may suggest, non-hierarchical controls like the ListBox and the Combo can be bound only to a flat data, whereas the TreeView and the Menu can be bound both against flat and hierarchical data. Let's take a look at the simpler, flat binding first.

Binding to non Hierarchical Data

We have tried to provide easy and straightforward way to declarative bind a control against OData service. If you take a look at the well known WebService section, you will notice that there is a new nested property available - ODataSettins. And since they say a code block is worth a thousand words, here is one:

<telerik:RadListBox runat="server" ID="RadListBox1">
                    <WebServiceSettings Path="http://services.odata.org/OData/OData.svc">
                        <ODataSettings ResponseType="JSONP">
                            <Entities>
                                <telerik:ODataEntityType Name="Category" DataTextField="Name"               DataValueField="ID" />
                            </Entities>
                            <EntityContainer>
                                <telerik:ODataEntitySet EntityType="Category" Name="Categories" />
                            </EntityContainer>
                        </ODataSettings>
                    </WebServiceSettings>
                </telerik:RadListBox>
What is going on here? Let's find out!
  • First, lets take a look at the Path property. As expected, this should be the service url, without any query string parameters.
  • Secondly, there is the ResponseType property. Normally, it is not possible for the XMLHttpRequest objet to make requests for resources in another domain due to XSS restrictions. The JSONP hack is a common workaround for this behavior. Without getting into details, should the service you need to access is in another domain, set the ResponseType to JSONP
  • The next thing to note is the Entities collection. You think of entities as structured records consisting of named and typed properties with a key. Each entity has DataTextField and DataValueField. Normally, the DataValueField maps to the enitity key and the DataTextField to a text field that you want to see displayed in the control. For now, it is not possible to have more than one text fields, however, we will improve that in the future.
  • Lastly, there is the EnityContainer collection, a collection of EnititySets. What is an EntitySet? Well, this is a mapping betwen an entity type and the respective service collection that holds entries of that type. Each EntitySet has an EntityType and a Name property. The Name property stands for the name of the collection, like http://ODataService.svc/<< NAME >> and the EntityType specifies entries of what ODataEntityType are stored in there.

If you take a look at the OData sample service metadata document, you will notice a lot in common. This is on purpose. We have tried to mimic the metadata declaration structure as much as possible, so developers already working with OData have easy time when binding RadControls against OData services. On the other hand, we believe that this approach is straightforward and easy to grasp for developers that don't have any experience with OData as well.

Binding to Hierarhical Data

Binding to hierarchical data sounds a bit more challenging, fortunately, in this case it is not :) First, lets take a look at a sample JSON returned from OData service:

{
        "d" : [
                {
                    "__metadata": {
                        "uri": "http://services.odata.org/OData/OData.svc/Categories(0)", "type": "ODataDemo.Category"
                    },
                    "ID": 0,
                    "Name": "Food",
                    "Products": {
                        "__deferred": {
                            "uri": "http://services.odata.org/OData/OData.svc/Categories(0)/Products"
                        }
                    }
            ]
        }

What you see is an entry of type Category, with the following properties: ID, Name and Products. Apparently, the Products property is marked as "__deferred" and an URL is provided. This is the URL of the related Products, which are going to be accessed on demand. Let's use a TreeView to display that! We have a hierarchy of two levels, on the first level there are the Categories and on the second, the Products for each Category. Here is the needed markup:

<telerik:RadTreeView runat="server" ID="RadTreeView1">
            <WebServiceSettings Path="http://services.odata.org/OData/OData.svc">
                <ODataSettings ResponseType="JSONP">
                    <Entities>
                        <telerik:ODataEntityType Name="Category" DataTextField="Name" DataValueField="ID" NavigationProperty="Products" />
                        <telerik:ODataEntityType Name="Product" DataTextField="Name" DataValueField="ID" />
                    </Entities>
                    <EntityContainer>
                        <telerik:ODataEntitySet Name="Categories" EntityType="Category" />
                        <telerik:ODataEntitySet Name="Products" EntityType="Product" />
                    </EntityContainer>
                </ODataSettings
            </WebServiceSettings>
        </telerik:RadTreeView>

The Path and the ResponseType properties are the same as in the flat binding. The hierarchy is build in the following way:
  • First, we declare the Entity types as in the flat binding. It is recommended to take a look at the given service metadata document and chose ID and Text fields.
  • Lets build the hierarchy now. Each EntityType has a NavigatonProperty property. It's function is to create the hierarchy. In this case, we need to set the CategoryNavigationProperty to Products.
  • In the EntityContainer collection we match Collection to EntityType, as in the flat binding.
That's it all! You can check out the same tree view in action here. All client events that are normally used with WebServices work with OData as well.

What's Next?

OData support for RadScheduler is on the way, also, we will update the current functionality to cover more widely the OData specification. We will add support for:
  • Bind to a web method
  • Add support for query string options like OrderBy, Select or Top.
If you want to see something more added or have any feedback on the implementation, feel free to drop us a line. As usual, any feedback is higly appreciated :)

Genady-Sergeev
About the Author

Genady Sergeev

is a Senior Manager in the Progress Web UI & Tools division, which develops the Kendo UI, UI for ASP.NET MVC and UI for ASP.NET AJAX products. He joined the company back in 2009 and since then he has been involved with the web UI products on a variety of levels, from a single contributor to a senior manager. Genady's main interests are in the field of client-side development and he is a big fan of the DevOps philosophy. In his free time he likes skiing and cross-country cycling.

Comments

Comments are disabled in preview mode.