Reputation: 380
I have been using the WebAPI in ASP.Net to allow access to our Entity Framework Objects. The problem I am having is converting the objects to a custom POCO for our end customers to use. I need to convert the Entity Framework Object to a custom POCO.
For example in our SQL Database we have Tbl_Person with the following properties
PersonID FirstName SureName DateOFBirth AnnualSalary
This table maps to an Entity Framework class Person with the same properties. But I want to change the properties so that when a end customer accesses it they get a POCO like:
PersonID Name Age SalaryRange
I also want to keep the current features such as JSON & XMLoutput and allow for OData queries. I have been trying to 'Collect' the Odata Query and applyto my database context but this does not seem to be work correctly Please see code example below:
Imports System.Net
Imports System.Web.Http
Imports System.Data.Entity
Public Class PeopleData
Inherits DbContext
Public Property People() As DbSet(Of Person)
End Class
Public Class Person
Public Property PersonID() As Integer
Public Property FirstName() As String
Public Property SureName() As String
Public Property DateOFBirth() As Date
Public Property AnnualSalary() As Integer
End Class
Public Class PeopleController
Inherits System.Web.Http.ApiController
Private db As New PeopleData
Function GetPeople(query As OData.Query.ODataQueryOptions(Of Person)) As IQueryable(Of apiPerson)
Dim pep = query.ApplyTo(db.People)
Dim resPep As New List(Of apiPerson)
For Each p In pep
resPep.Add(New apiPerson(p))
Next
Return resPep.AsQueryable
End Function
End Class
Public Class apiPerson
Public Sub New(ByVal p As Person)
PersonID = p.PersonID
Name = p.FirstName & " " & p.SureName
Age = Date.Now.Year - p.DateOFBirth.Year
If p.AnnualSalary > 15000 Then
SalaryRange = "High"
Else
SalaryRange = "Low"
End If
End Sub
Public Property PersonID() As Integer
Public Property Name() As String
Public Property Age() As Integer
Public Property SalaryRange() As String
End Class
I have two problems:
1) The API help pages don't populate and only produce this error: 'Sample not available.' I like the dynamic help pages & that they pick up code comments, this is a really quick and easy way to maintain documentation. How can I get them to work with the ApiPerson?
2) If I try /api/people?$filter=Age eq 29 I get an error Type 'MvcApiPeople.Person' does not have a property 'Age'. I understand that the LINQ Query is been passed to the 'Person' and that property does not exist but how can I 'Translate' queries to map to different properties in the actual Database Object?
Upvotes: 0
Views: 538
Reputation: 380
After playing around with many different solutions I decided the simplest way to control the information that is made available on an API and still allow iQueryable is to control the data at database level or at class level with Data Contract annotations.
I actually created views in my database to render the data exactly how I want it to appear for end customers. I felt this had the best benefits for performance and speed of implementation.
Thank you to all the guys who offered suggestions.
Upvotes: 0
Reputation: 351
Regarding your question 1:
I think your problem is that the apiPerson-class is missing a parameterless constructor.
Also, I found a blog post with some information on how to customize sample generation when the default generation mechanism doesn't work:
Upvotes: 0
Reputation: 6793
Your action declaration should be
Function GetPeople(query As OData.Query.ODataQueryOptions(Of apiPerson)) As IQueryable(Of apiPerson)
i.e query parameter should be of type ODataQueryOptions (Of apiPerson)
not ODataQueryOptions (Of Person)
.
Upvotes: 1