Open Types In OData With Web API

Introduction

Open type is a structured type which contains dynamic properties. It allows the client to add properties to the instance of object or class dynamically by specifying unique name and value. Our data model becomes more flexible by using open type. The value of these dynamic properties can be anything; i.e., primitive type, complex type, enumeration type, collection of any type. In this article, we will learn how to use open type in Web API with OData.

Example

My article "An OData V4 Endpoint with ASP.NET Web API 2.2" explains how to configure OData endpoint with ASP.NET Web API. I have taken the same example here. Now to support the Open Type just a little bit changes in model class and model new definition as following.

  1. namespace WebAPITest  
  2. {  
  3. using System.Collections.Generic;  
  4. public class TestData  
  5. {  
  6. public int Id { getset; }  
  7. public string Name { getset; }  
  8. public string Role { getset; }  
  9. public IDictionary<stringobject> DynamicProperties { getset; }  
  10. }  
  11. }  
To Create or support the open type class (CLR type) must have property of type IDictionary<string, object> that used to hold the dynamic properties.

Now I run this application and try to get service Meta data.

URL: http://localhost:24367/$metadata

Output:

Output

The metadata does not include the Dynamic Properties property for the TestData class. The metadata only includes its declared properties. EntityType ‘s OpenType property is set to true.

Here to check dynamic properties, I have added POST method in to the OData controller. To test the application, I am using Telerik's Fiddler. It’s free. Using Fiddler, we can analyze the input / output of URL and also able to POST data without any user interface.
  1. public HttpResponseMessage Post([FromBody]TestData entity)  
  2. {  
  3. int id = DALTestData.Testdata.Max(p => p.Id) + 1;  
  4. entity.Id = id;  
  5. DALTestData.Testdata.Add(entity);  
  6. return Request.CreateResponse(HttpStatusCode.OK, entity);  
  7. }  
Now I am posting 3 dynamic properties named test1, test2 and test3 along with the model. Here we can see that dynamic properties are automatically bound to the IDictionary type property.

Posting the dynamic property using Fiddler

Fiddler

Here I set a break point to the POST method in the controller. We can see that additional properties are added to the dictionary.

properties

Same as using the GET request, we can get the dynamic property at client end. In this example, I have assigned the value of DynamicProperties of TestData class in Static data source.
  1. namespace WebAPITest  
  2. {  
  3. using System.Collections.Generic;  
  4. public class DALTestData  
  5. {  
  6. public static List<TestData> Testdata = new List<TestData>();  
  7. static DALTestData()  
  8. {  
  9. Testdata.Add(new TestData { Id = 1, Name = "Jignesh", Role = "Project Manager", DynamicProperties = new Dictionary<stringobject>() { { "Test1""Test1" } } });  
  10. …..  
  11. …..  
  12. }  
  13. }  
  14. }  
GET method in Controller
  1. public HttpResponseMessage Get([FromODataUri]int key)  
  2. {  
  3. TestData data = DALTestData.Testdata.Where(k => k.Id == key).FirstOrDefault();  
  4. if (data == null)  
  5. {  
  6. return Request.CreateResponse(HttpStatusCode.NotFound);  
  7. }  
  8.   
  9. return Request.CreateResponse(HttpStatusCode.OK, data);  
  10. }  
URI: http://localhost:24367/TestData(1)

Output:

Output

Summary

In this way OData enables us to add dynamic properties in to our model class. This feature is very important when client wants to send some additional data other than property of model.


Similar Articles