Determining if a Service is OData compliant

This document contains code samples and is considered intermediate to advanced. A working knowledge of Visual Studio, the C# programming language, and respective terminology is assumed.

The OData specification was originally described by the Microsoft corporation under the Microsoft Open Specification Promise. However, compliance to a standard can be subjective and may mean that not all services are fully compliant or contain errors in their structure. Due to this, the K2 OData Service Broker may display strange behaviour if the service is not fully OData compliant. The steps in this topic explain how to “test” an OData service for compliance, before attempting to register an OData Service Instance or generating and using SmartObjects through this Service. .

The steps described here will also aid troubleshooting to determine whether a problem/error resides with the service or with the K2 OData service broker.

Required Resources

If you wish to test this approach with a known-working service, paste the following url into a browser of your choice: 
http://services.odata.org/V3/(S(readwrite))/OData/OData.svc/

This will generate a sample “readwrite” OData service that you can use for testing this approach.

For example:

Results in the following sample service URL:

Testing the Service

To get started, you need to create a Service Reference within your project. Create a Visual Studio Console Application, naming it for example ‘OData Test Service’.Once your project is up and running, follow the steps below:

  1. From the Project Explorer, right on click on References and select Add Service Reference
  1. The Add Service Reference dialog appears
  1. Enter the OData service URL into the field labelled Address
  2. Enter a Namespace name for example: ODataService
  3. Click Go
  1. There may be a delay as the data is downloaded, should it be successful you will be able to view the Services in the tree view labelled Services. Click OK to complete.
  1. If successful, the project explorer will update as shown below:
  1. Add the following references to you project
  1. System.Net
  2. Namespace + Service Name ie: TestODataService.ODataService
  1. The goal from this point forward is to determine the level of compliance your service has with OData.  If you’ve successfully made it to this step then some major hurdles have already been cleared.  They include having a $metadata document available and having entities which ALL have primary keys among others.
  1. Next you will need to write soem code to verify that the service can perform the operations you wish to expose. The code will depend on the service you intend to consume. The code sample below illustrates testing the generic OData service URL described in the required resources section.
  2. namespace TestODataService {
    					class Program {
    					static void Main(string[] args) {
    					DemoService demoService = new DemoService(new Uri("http://services.odata.org/V3/(S(jtqzg2omvsfijmswesaplibf))/OData/OData.svc/"));
    
    					//Fill this property in with your relevant credentials.
    					demoService.Credentials = CredentialCache.DefaultNetworkCredentials;
    
    					//Test listing on entitiesvar products = demoService.Products.ToList();
    					var categories = demoService.Categories.ToList();
    					var suppliers = demoService.Suppliers.ToList();
    					//etc....//Test loading an entityvar product5 = demoService.Products.Where(x => x.ID == 5).FirstOrDefault();
    
    					//Test updating an entity
    					product5.Name = "UpdatedTestProduct";
    					demoService.UpdateObject(product5);
    					demoService.SaveChanges();
    
    					//Test creating an entityProduct newProduct = new Product() {
    					ID = 253, //The primary key(s) of the entity must always be set //(in this case the key is the ID property)
    					Name = "NewTestProduct",
    					Description = "Testing",
    					Rating = 8
    					/* etc... */
    					};
    
    					//For inherited types use the BaseType //(e.g. when testing the inherited entity DemoService.FeaturedProduct, use //typeof(DataServiceQuery<Product>) as shown)var productsQueryType = typeof(DataServiceQuery < Product > );
    					var entitySetName = typeof(DemoService).GetProperties()
    					.Where(x => x.PropertyType == productsQueryType).FirstOrDefault().Name;
    
    					demoService.AddObject(entitySetName, newProduct);
    					demoService.SaveChanges();
    					}
    					}
    			}
  1. The above program can be modified to test any OData service that isn’t behind a client certificate or OAuth.  Should any of the operations fail, then there are a few things to check.
  1. First, make sure your service allows full access to each entity.  It’s perfectly acceptable to allow reads but not writes and vice versa. 
  2. On that note, services can also restrict the number of records you can pull on each request, so the entire entityset may not come back when listing.  Filtering or paging code would need to be written in this sample to overcome this.  The OData service broker accommodates this already.
  3. Another source of strange behaviour could be an attached resource stream on the entity.  If this is the case then the error should be fairly clear and indicate that no media or named resource stream was set.
  4. Bad credentials could also be a source of issues.  If your service needs more advanced authentication such as OAuth or an X.509 client certificate, then additional code would need to be written into the sample above.  For OAuth you can set the Bearer token in the headers by adding to the SendingRequest2 event on the DataServiceContext (DemoService class in this example).  For X.509 certificates the code necessary to test with them is outside of the scope of this document.  It involves compiling a dll at runtime using the EntityClassGenerator.
  1. If all the points in step 8 have been checked but you still experience trouble. then there is a strong likelihood that your service is not OData compliant in some way.  To determine the exact way in which your service is not compliant, you will need to consult the OData spec.

The full spec can be found at:

http://www.odata.org/documentation/odata-version-3-0/

This is a view of the page as of February 2015.  As this page is liable to change overtime, some searching may be necessary to find the documents describing the complete OData spec.

Additional resources for testing for OData compliance

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/calling-an-odata-service-from-a-net-client