Introduction
It's not easy to choose the right technology for a specific problem sometimes. This article provides a decision making process on OData technology selection in an environment with both .NET C# and Java applications running. It also provides code samples on how to create an OData RESTful service in .NET C# and sample code to consume the service in a Java application. OData interoperability looks great in these .NET and Java applications.
Background
We need to retrieve large data from oracle database and serialize the data in JSON format in a .NET C# application in Data Center A so that the JSON data can be consumed in a Java application in a Data Center B. The technology selection decision process has two steps.
Step 1: Do we use Web API with OData or WCF RESTful service using JSON.NET in the .NET application?
After researching online, we decided to use Web API with OData based on the following OData advantages.
- An open protocol which allows the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way.
- Microsoft initiated OData in 2007. OData v4 was standardized at OASIS.
- Can be interoperable with .NET, Java, PHP, iPhone, Android and more
- Is an OASIS standard that defines the best practices for building and consuming RESTful APIs.
- Helps you to focus on business logic without having to warry about the request/response headers, HTTP methods, media types, payload formats, and query options, etc
- Guides you about tracking changes, defining functions/actions for reusable procedures and sending asynchronous/batch requests etc.
- Provides facility for extension to fulfill any custom needs of your RESTful APIs
Step 2: Do we use odata4j or Apache Olingo library in the Java application?
After researching online, we decided to use Onlingo library in Java application because of the following.
- odata4j library is not going to support OData v4
- Apache Olingo serves client and server aspects of OData. It currently supports OData 2.0 and will also support OData 4.0. The latter is the OASIS version of the protocol: OASIS Open Data Protocol (OData) TC.
The next question is: How to make it working in the .NET C# and Java applications?
The tools and packages on the .NET C# side are as the following:
- Visual Studio 2015 with ASP.NET 5
- latest Microsoft.AspNet.Odata (e.g. OData 5.9.0)
- latest EntityFramework (e.g. EF 6.1.3)
The Tools and packages on the Java side are as the following:
- Eclipse Kepler (Not the latest version because Olingo library was tested on Juno and Kepler)
- Apache Olingo Library 4.2
- Maven 3.2.1
Using the code on .NET C# Side
There are great OData Tutorials at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api. However, the sample code may not work if you are not using Visual Studion 2012 or 2013. I will just high-light the steps here and explicitly mention the configuration change in step 4 if you are using Visual Studio 2015. I will also attached the complete sample code at the end just in case.
Step 1: Create a new Visual Studio project
In Visual Studio, from the File menu, select New > Project.
Expand Installed > Templates > Visual C# > Web, and select the ASP.NET Web Application template. Name the project "ODataPartService"
In the New Project dialog, select the Empty template. Under "Add folders and core references...", click Web API.
Step 2: Install the OData Packages
From the Tools menu, select NuGet Package Manager > Package Manager Console. In the Package Manager Console window, type:
Install-Package Microsoft.AspNet.Odata
Step 3: Add a Model Class
In Solution Explorer, right-click the Models folder. From the context menu, select Add > Class. Name the class Product. Here is the sample code in Product.cs file,
namespace ProductService.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
}
Step 4: Enable Entity Framework
From the Tools menu, select NuGet Package Manager > Package Manager Console. In the Package Manager Console window, type:
Install-Package EntityFramework
Open the Web.config file, and add a connectionStrings element inside the configuration
element, after the configSections
element. Note: the Data source is not (localdb)\V11.0 but locadb\MSSQLLocalDB
<connectionStrings><add name="ProductsContext" connectionString="Data Source=(localdb)\MSSQLLocalDB;
Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
AttachDbFilename=|DataDirectory|ProductsContext.mdf"
providerName="System.Data.SqlClient" /> </connectionStrings>
Next, add a class named ProductsContext
to the Models folder:
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
}
Step 5: Configure the OData endpoint
Added the following code to the Register
method:
public static void Register(HttpConfiguration config)
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Products");
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: builder.GetEdmModel());
}
Step 6: Add OData Controller and Query Entity Set
In Solution Explorer, right-click the Controllers folder and select Add > Class. Name the class ProductsController.
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
private bool ProductExists(int key)
{
return db.Products.Any(p => p.Id == key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
Query Entity Set. More methods can be found in the OData Tutorial and in the attached code.
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
IQueryable<Product> result = db.Products.Where(p => p.Id == key);
return SingleResult.Create(result);
}
Step 7: Add a .NET C# Client to consume the OData service
Follow the tutorial at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-client-app or just use the attached code to build a c# client to consume the created OData v4 service. Note: There is no file called ProductClient.odata.config after the code generation if you use Visual Studio 2015. Instead, the OData service url needs to be modified in the ProductClient.tt file. Here is the sample code.
public static class Configuration
{
public const string MetadataDocumentUri = "http://localhost:38173/";
public const bool UseDataServiceCollection = true;
public const string NamespacePrefix = "ProductsApp";
public const string TargetLanguage = "CSharp";
public const bool EnableNamingAlias = true;
public const bool IgnoreUnexpectedElementsAndAttributes = true;
}
Using the code on Java Side
There are great Olingo tutorials at https://olingo.apache.org/doc/odata4/index.html
However, the instruction may not work for you if your compuer is behind a proxy server and/or any other unknown issues with your computer. I encounterd the following issues when I tried my Java client to consume the OData service created in .NET C#.
Issue 1: Proxy issue when using Maven 3.2
The issue can be solved by adding a proxy element inside proxies element in the settings.xml config as the following. Note: The settings.xml file may not be in the Maven user default folder c:\Users\xxxx\.m2 Fdirectory. Instead, it may be in the Maven installation folder. e.g. C:\apache-maven-3.2.1\conf directory. Make sure to modify the correct settings.xml config file.
<proxy>
<id>optional</id>
<active>true</active>
<protocol>http</protocol>
<username>username</username>
<password>password</password>
<host>roxy.yourdomain</host>
<port>80</port>
<nonProxyHosts>maven.org|apache.org</nonProxyHosts>
</proxy>
Issue #2: Maven error when importing a sample Olingo Maven project. Here is the error.
http://www.codeproject.com/KB/webservices/1093859/ODataJavaError1.JPG
The issue can be solved by disabling Maven nature first.
http://www.codeproject.com/KB/webservices/1093859/ODataJavaError2.JPG
Then converting the project back to a maven project.
http://www.codeproject.com/KB/webservices/1093859/ODataJavaError3.JPG
Issue #3: The Quick start guide is for OData v2 not for v4.
If you are using the latest OData v4 as explained in this article, be sure to select the right client sample to start with. It's better to use the Client sample with the Olingo source download package. Here are some sample codes to consume OData v4 servcie created in .NET C#. It should work with Java service as well because the sample client in the Olingo library uses a Java service as a test servcie.
public class OlingoSampleApp {
private ODataClient client;
public OlingoSampleApp() {
client = ODataClientFactory.getClient();
}
public static void main(String[] params) throws Exception {
OlingoSampleApp app = new OlingoSampleApp();
app.perform("<a href="http:
}
void perform(String serviceUrl) throws Exception {
Edm edm = readEdm(serviceUrl);
List<FullQualifiedName> ctFqns = new ArrayList<FullQualifiedName>();
List<FullQualifiedName> etFqns = new ArrayList<FullQualifiedName>();
for (EdmSchema schema : edm.getSchemas()) {
for (EdmComplexType complexType : schema.getComplexTypes()) {
ctFqns.add(complexType.getFullQualifiedName());
}
for (EdmEntityType entityType : schema.getEntityTypes()) {
etFqns.add(entityType.getFullQualifiedName());
}
}
public Edm readEdm(String serviceUrl) throws IOException {
EdmMetadataRequest request = client.getRetrieveRequestFactory().getMetadataRequest(serviceUrl);
ODataRetrieveResponse<Edm> response = request.execute();
return response.getBody();
}
}
.NET OData v4 Service: http://www.codeproject.com/KB/webservices/1093859/ProductService.zip
.NET OData Client: http://www.codeproject.com/KB/webservices/1093859/ProductsApp.zip
Java Client: http://www.codeproject.com/KB/webservices/1093859/OlingoSampleApp.zip
References
- Wikipedia, 2015, Open Data Protocol, https://en.wikipedia.org/wiki/Open_Data_Protocol
- OData team, 2015, OData – the best way to REST; http://www.odata.org/
- JC Cimetiere, 2010, OData interoperability with .NET, Java, PHP, iPhone and more; https://blogs.msdn.microsoft.com/interoperability/2010/03/16/odata-interoperability-with-net-java-php-iphone-and-more/
- Mike Wasson, 2014, OData, http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api
- Apache Olingo Team, 2015, How to use Apache Olingo as Client Library, https://olingo.apache.org/doc/odata2/tutorials/OlingoV2BasicClientSample.html
- Apache Olingo team, 2015, Documentation Odata 4.0 Java Library, https://olingo.apache.org/doc/odata4/index.html
- Odata4j team, 2015, odata4j, https://code.google.com/archive/p/odata4j/
- Yi Ding, 2014, odata4j support for OData version 4.0, http://stackoverflow.com/questions/23333413/odata4j-support-for-odata-version-4-0
Points of Interest
It's interesting to write an article in here. It will be good if a member can upload an existing document.
History
Initial post