Showing posts with label odata. Show all posts
Showing posts with label odata. Show all posts

May 20, 2014

Hosting ASP .NET MVC4 and WCF Data Service together with Entity Framework 6.1.0 [Expression of type 'System.Data.Entity.Core.Objects.ObjectContext' cannot be used for return type 'System.Data.Objects.ObjectContext']


I had to work on a POC which is based on ASP .NET MVC4 and Entity Framework 6.1.0, we also want to enable WCF Data Service in the same project. I faced few issues, which took some time for me to fix, so thought of writing it here:

As usual I created a ASP.NET MVC4 project (Internet application) using VS 2012 and as expected it worked fine:


Now I installed latest entity framework using Nuget, the version got installed is EntityFramework.6.1.0



As next step I created entity data model classes based on NorthWind database.



Next created a WCF Data service and configured it to use NorthWindEntites (see below selected section in red box)



I tried running the MVC app and browsing to 'NorthWindService.svc', but got the error:


Server Error in '/' Application.

The resource cannot be found.   Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name ...


After few trial and error found that this error can be fixed by adding following line in 'RegisterRountes' function in App_start\RoutingConfig.cs

routes.IgnoreRoute("NorthWindService.svc/{*pathInfo}");

Executed again, better this time i am not getting 404 error now but got another error:

Request Error: The server encountered an error processing the request. See server logs for more details

To debug this further, I again started debugging and enabled "Common Language Runtime Exceptions" from "Exception Dialog" (Ctr + Alt + E).

Browsing to http://localhost:1234/NoerhWindService.svc cause VS 2012 to throw below exception:

Expression of type 'System.Data.Entity.Core.Objects.ObjectContext' cannot be used for return type 'System.Data.Objects.ObjectContext'

I found this blog http://blogs.msdn.com/b/odatateam/archive/2013/10/02/using-wcf-data-services-5-6-0-with-entity-framework-6.aspx, which clearly says to use Entity Framework 6.* as data provider for a Data service class, the service needs to be derived from EntityFrameworkDataService<T> intead of DataService<T>


To get 'EntityFrameworkDataService' you need to install 'WCF Data Services Entity Framework Provide' nuget package https://www.nuget.org/packages/Microsoft.OData.EntityFrameworkProvider/1.0.0-alpha2

Run the command:

Install-Package Microsoft.OData.EntityFrameworkProvider -Pre

in Nuget Package Manager Console (Tools => Nuget Package Manager => Package Manager Console)

Update your data service class to inherit from EntityFrameworkDataService.


Now tried again browsing to http://localhost/NorthWindService.svc, this time it worked and i got the metadata!!

Few thing to note, when you add WCF Data service, following versions of packages will be added:

Microsoft.Data.Edm.5.2.0
Microsoft.Data.OData.5.2.0
Microsoft.Data.Services.5.0.0
Microsoft.Data.Services.Client.5.0.0

Once you install 'WCF Data Services Entity Framework Provider' (Microsoft.OData.EntityFrameworkProvider.1.0.0-alpha2), all the above packages will be updated to new versions:

Microsoft.Data.Edm.5.6.0
Microsoft.Data.OData.5.6.0
Microsoft.Data.Services.5.6.0
Microsoft.Data.Services.Client.5.6.0

Everything is working on my local environment now. I deployed this basic application to Microsoft Azure and browsing to data service threw below error:

Could not load file or assembly 'Microsoft.Data.Services, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

See data service is still trying to use version 5.0.0.0 of Microsoft.Data.Services, but installation of 'WCF Data Services Entity Framework Provider' updated the references to Microsoft.Data.Services 5.6.0.

If you open  the .svc file [right-click it, select View Markup] then you can see it still contains following line:

<%@ ServiceHost Language="C#"
  Factory="System.Data.Services.DataServiceHostFactory,
          Microsoft.Data.Services, Version=5.0.0.0,
          Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  Service="MVC4WCFDataServiceFE5.NorthWindService" %>

Just update the version number to '5.6.0.0' as below and all started working.

<%@ ServiceHost Language="C#"
  Factory="System.Data.Services.DataServiceHostFactory,
          Microsoft.Data.Services, Version=5.6.0.0,
          Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  Service="MVC4WCFDataServiceFE5.NorthWindService" %>

January 2, 2012

OData PHP Producer


The OData PHP Producer library is a server side implementation of OData Protocol using PHP.

I was involved in the design and implementation of this library, thought of sharing some high level details of this project.

The "OData PHP Producer" is designed in a generic way such that you can expose data from any data source ( relational database, file system etc..)

The above diagram shows the high-level design of "OData PHP Producer" library and a set of sample services (NorthWind, WordPress). These sample services can be used as a reference to write your own service. Each sample service has the following components:

·         IServiceProvider and IDataService implementation, the main service entry point.
·         IDataServiceMetadataProvider implementation.
·         IDataServiceQueryProvider implementation.
·         IDataServiceStreamProivder implementation [optional].

The flexibility of exposing data from any data source requires the end developer, the one want to expose the data as OData service, to implement the above set of interfaces defined by the "OData PHP Producer" library.

1.     IDataServiceMetadataProvider:

Purpose of implementation of this interface is to let the "OData PHP Producer" library know the metadata of your data source, then the library will exposes a $metadata endpoint which can be used by the clients to fetch the service metadata document that describes how the service exposes the data and what structures and data types they should expect

2.     IDataServiceQueryProvider:

The library don't know anything about the underlying data source such as how to connect, how to query etc.. It’s the responsibility of the end developer to connect to the data source, fetch the data and give it to library based on the delegates invoked by the library.

The OData protocol defines URI conventions to address the resources in your data source and to control the amount and order of the data that an OData service returns for the resource identified by the URI. The library has the code to parse the incoming OData queries, these queries are translated into call to IDataServiceQueryPorivder methods

Note that there are two versions of Query Provider interface, IDataServiceQueryProvider and IDataServiceQueryProvider2. The IDataServiceQueryProvider2 is same as IDataServiceQueryProvider except  one difference that with IDataServiceQueryProvider library does the filtering using built-in expression provider and if result-set is huge then  performance of the library will not up to the marks.
The IDataServiceQueryProvider2,library generates the filter criteria with the help of custom expression provider and the IDataServiceQueryProvider2 can use this filter criteria to run query on the data source. So in this case library don’t need to scrub out the unnecessary records to get the final subset of data.

3.     IDataStreamProvider:

This is an optional interface that can be used to enable streaming of content such as Images or other binary formats

4.     IServiceProvider and IDataService:

IDataService is the interface that deals with the service endpoint and allows defining features such as Page size for the OData Server paging feature, access rules to the service, OData protocol version(s) accepted and so on. IServiceProvider is the interface that deals with access to the above interface implementations from the library.
                                                              ================

Before going into the details of implementing the above interfaces for your data source let us configure the "OData PHP Producer" library and associated sample service based on MySQL WordPress database.


Configuring the library and running MySQL based OData service on Windows

Prerequistes


1.      PHP version > 5.3.x
          Download and install PHP.
          Refer this link to configure PHP on IIS.
2.   IIS UrlRewrite Module
          Download and install IIS URL Rewrite module from here
3.   MySQL
4.   The sample service showcasing how to expose a MySQL database as OData Service uses WordPress database. Download and install WordPress from here

Installation


1.      Download the latest "OData PHP Producer" from official github site https://github.com/MSOpenTech/odataphpprod

2.      Extract the zip file to your local drive, for example E:\



3.      Add the path to the ‘library’ folder to the 'include_path' directive in php.ini. e.g.

   include_path = ".;E:\OData Producer for PHP\library"

4.      Create a website in IIS using the content of “OData Producer for PHP” directory.


5. Open the file

[root]\OData Producer for PHP\services\IDataServiceQueryProvider2 Implementation\WordPress\ wordpressQueryProvider.php

Update the value of connection parameters DB_NAME, DB_USER, DB_PASSWORD and DB_HOST so that it points to your WordPress MySQL database


 6. Restart IIS by running iisreset command from command prompt

7. Your service is ready :), open your browser and go to the website we created in step4, append the service name 'WordPress2.svc' to the root URL.

e.g: http://localhost:8083/WordPress2.svc

This will cause the "OData PHP Producer library"to return the Service Document of WordPress data service.



You can refer official OData site for more about URI options supported by  an OData service.
Here few service URI that you can try:
* http://localhost:8083/WordPress2.svc/$metadata
       Fetches the metadata of WordPress database.
* http://localhost:8083/WordPress2.svc/Posts
       Fetches post entity instances from the database
* http://localhost:8083/WordPress2.svc/Posts?$expand=Category
       Fetches the post entity instances and category instance associated with each post.