Book Image

OData Programming Cookbook for .NET Developers

By : Juntao Cheng
Book Image

OData Programming Cookbook for .NET Developers

By: Juntao Cheng

Overview of this book

Odata (Open Data Protocol) is a Web protocol for querying and updating data that provides a way to unlock your data and free it from silos that exist in applications today. OData enables data access among a variety of applications, services, and stores by adopting existing Web technologies such as HTTP, XML, and JSON. This book deals with common OData programming cases over the Microsoft .NET Framework platform and eases the learning curve for a .NET developer to start incorporating OData in data service development.This book provides a collection of recipes that help .NET developers to get familiar with OData programming in a quick and efficient manner. The recipes cover most OData features from the former ADO.NET Data Service to the current WCF Data Service platform. In addition, all the sample cases here are based on real-world scenarios and issues that .NET developers might come across when programming with OData in application development.This book will be your handy guide with basic to advanced walkthroughs of common OData programming cases for the Microsoft .NET Framework platform. You will learn quick solutions to necessary tasks to integrate the power of OData at both server-side and client-side.This book will help you master the use of OData with .NET Framework by taking you through hands-on and practical recipes. It starts by talking about the common means for building OData services and consuming OData services in client applications. Then, some more specific topics like hosting, configuration and security are discussed. The book also covers many popular and interesting topics such as integrating OData in web applications, and developing data-driven mobile applications with OData. Moreover, you can also find quite a few recipes discussing real-world OData producers and new features in latest and future versions.Within "OData Programming Cookbook for .NET Developers", all the recipes are selected based on real-world scenarios that you will commonly come across. Each recipe covers a specific topic, going from the description of the problem, through a conceptual solution, to a solution containing sample code. By following these recipes, you can acquire how to program with OData in a simple, effective, and easy manner.
Table of Contents (15 chapters)
OData Programming Cookbook for .NET Developers
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface

Using custom data objects as the data source of WCF Data Service


So far we've explored several examples, which use relational database objects as the data provider (through Entity Framework, LINQ to SQL, or custom operations). However, we're definitely not limited to these data sources; WCF Data Service provides the flexibility for developers to use custom CLR objects as data sources.

In this recipe, we will see how to use custom data objects as a WCF Data Service data source and expose OData entitiy sets based on the data members of the custom data objects.

Getting ready

In this recipe, we will create a WCF Data Service for exposing some books and book categories information to clients. Instead of using ADO.NET Entity Framework or LINQ to SQL, we will define some custom CLR types to represent the data model of the sample service.

The source code for this recipe can be found in the \ch01\CLRObjDataServiceSln\ directory.

How to do it...

  1. 1. Create a new ASP.NET Empty Web Application.

  2. 2. Create custom CLR types to represent the book and book category items.

    The following code snippet shows the definition of the sample CLR types:

    namespace CLRObjDataService
    {
    [DataServiceKey("ISBN")]
    [DataServiceEntity]
    public class BookInfo
    {
    public string ISBN { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public DateTime PubDate { get; set; }
    public BookCategory Category { get; set; }
    }
    [DataServiceKey("Name")]
    [DataServiceEntity]
    public class BookCategory
    {
    public string Name { get; set; }
    public List<BookInfo> Books { get; set; }
    }
    }
    
  3. 3. Create a data context type that acts as a container for entity sets based on the custom CLR types (defined in the previous step).

    The following is the code of the sample data context type (see the following BookServiceContext class), which exposes two entity sets based on the BookInfo and BookCategoryx classes:

    public class BookServiceContext
    {
    static IList<BookCategory> _categories = null;
    static IList<BookInfo> _books = null;
    public IQueryable<BookCategory> BookCategories
    {
    get
    {
    return _categories.AsQueryable();
    }
    }
    public IQueryable<BookInfo> Books
    {
    get
    {
    return _books.AsQueryable();
    }
    }
    }
    

    For demonstration, we have also defined a static constructor for generating some test data (see the following code snippet).

    static BookServiceContext()
    {
    _books = new List<BookInfo>();
    _categories = new List<BookCategory>();
    for(int i=1;i<=3;++ i)
    {
    var cate = new BookCategory() { Name = "Category_" + i.ToString() };
    cate.Books = new List<BookInfo>();
    for (int j = 1; j <= 3; ++j)
    {
    int bid = (i*10+j);
    var book = new BookInfo()
    {
    ISBN = "ISBN" + bid.ToString(),
    Title = "Book Title " + bid.ToString(),
    Author = "Author",
    PubDate = DateTime.Now,
    Category = cate
    };
    _books.Add(book);
    cate.Books.Add(book);
    }
    _categories.Add(cate);
    }
    }
    
  4. 4. Create a new WCF Data Service and use the custom data context type as its data source.

    The following code snippet shows the sample BookDataService class, which uses the BookServiceContext class (created in previous step) as the data source parameter:

    public class BookDataService : DataService< BookServiceContext >
    {
    public static void InitializeService (DataServiceConfiguration config)
    {
    config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
    }
    }
    

    Like the ADO.NET Entity Framework-based WCF Data Service, we also need to set the proper entity set access rules in the initialization function.

  5. 5. Launch the service and view the custom data entity sets in the web browser.

    For the sample service, we can access the exposed entity sets at the following locations:

    • Book category entity set (http://[server]:[port]/BookDataService.svc/BookCategories)

    • Book entity set (http://[server]:[port]/BookDataService.svc/Books)

    We can also use the following URL to retrieve book entities that belong to a certain category entity:

    http://[server]:[port]/BookDataService.svc/BookCategories('Category_1')/Books

    The following screenshot shows the book entities that belong to the first category entity:

How it works...

Now, let's take a look at what makes these things work. As we can see, each entity set we expose in the sample service is coming from its corresponding member property defined in the data context type. Such member properties should be declared as IQueryable<Entity Type> type so that the WCF Data Service runtime can correctly locate them and expose them as entity sets in the service.

Note

For a given entity type T, we can only define one member property (on the data context class), which returns IQueryable<T>. In other words, we cannot expose multiple entity sets using the same entity type.

For each custom entity type, we must specify a key property by using the DataServiceKeyAttribute attribute. This key property is used for identifying entity instances in a given entity set (just like the primary key for the relational table).

The BookCategory entity type has a Books property of the List<BookInfo> type. Such kind of entity collection properties will be automatically treated as Navigation properties on the target entity type. For OData clients, they can use these Navigation properties (by using relative URI address) to retrieve the associated subentities from the primary entity instance (see the previous sample code).

There's more...

We have discussed LINQ to SQL based data sources in the previous recipe. Actually, LINQ to SQL is a special case of a custom data object based data source, since the LINQ to SQL data model has already done most of the work for us. If you are interested in finding out more about building WCF Data Service data source with a custom CLR type, you can refer to the following MSDN reference:

Reflection Provider (WCF Data Services) available at http://msdn.microsoft.com/en-us/library/dd723653.aspx

See also

  • Adding custom operations on OData service recipe

  • Building an OData service with WCF Data Service and LINQ to SQL recipe