Data Access has been discontinued. Please refer to this page for more information.

Creating ASP.NET Web API Controllers

ASP.NET Web API allows you to serialize your persistent classes to JSON, XML, or some other format, and then write the serialized data into the body of the HTTP response message. As long as a client can read the serialization format, it can deserialize the object. Most clients can parse either XML or JSON. Furthermore, the client can specify which format it wants by setting the Accept header in the HTTP request message.

In this task, you will create Web API Controllers for your persistent classes. The CRUD operations they execute will become available by exposing the context class in the web application with the Repository pattern.

  1. As a first step, you need to configure the web application project to host Web API on IIS. To do so, you have to go through the SofiaCarRentalWebApp Project Configuration section.
  2. Next, you need to expose the FluentModel context class and the operations, which will be executed through it. For this purpose you will utilize the Repository pattern:

  3. Finally, you will implement the Web API controllers: a base controller, and a dedicated controller for each persistent entity in the model. Each specific controller will support the CRUD operations for the given persistent entity.

    The code for the task is available in the Web API Controllers C# and Web API Controllers VB sections of this tutorial.

SofiaCarRentalWebApp Project Configuration

  1. Integrate the SofiaCarRentalWebApp project with the Microsoft.AspNet.WebApi NuGet package. During the integration process, NuGet Package Manager will install the packages on which Microsoft.AspNet.WebApi depends:

    • Microsoft.AspNet.WebApi.WebHost
    • Microsoft.AspNet.WebApi.Core
    • Microsoft.AspNet.WebApi.Client
    • Newtonsoft.Json

      Allong with adding references to the downloaded assemblies, the package will do an additional modification to the SofiaCarRentalWebApp project. It inserts the required IIS configuration to the Web.config file.

      <system.webServer>
          <handlers>
            <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
            <remove name="OPTIONSVerbHandler" />
            <remove name="TRACEVerbHandler" />
            <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*"
                 type="System.Web.Handlers.TransferRequestHandler" 
                 preCondition="integratedMode,runtimeVersionv4.0" />
          </handlers>
      </system.webServer>
      
  2. Next, you have to add the default Web API route to the route table of the application:

    1. Open the Global.asax.cs(vb) file.
    2. Add the following references:

      using System.Web.Http;
      using System.Web.Routing;
      
      Imports System.Web.Http
      Imports System.Web.Routing
      
    3. Register the route in the Application_Start handler:

      RouteTable.Routes.MapHttpRoute(name: "DefaultApi",
                         routeTemplate: "api/{controller}/{id}",
                         defaults: new { id = RouteParameter.Optional });
      
      RouteTable.Routes.MapHttpRoute(name:="DefaultApi",
                             routeTemplate:="api/{controller}/{id}",
                             defaults:=New With {.id = RouteParameter.Optional})
      

Expose The Context Through The Repository Pattern C#

  1. In the SofiaCarRentalWebApp project, add a new class file called IOpenAccessBaseRepository.
  2. Paste the code of IOpenAccessBaseRepository in the newly added file.
  3. Do the same for the OpenAccessBaseRepository class. Its code is available in the BaseRepository tab below.
  4. Add a new class file called FluentModelRepositories and in it paste the code for the entity specific repositories. It is available in the Repositories tab below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Telerik.OpenAccess;
using Telerik.OpenAccess.FetchOptimization;

namespace SofiaCarRentalWebApp
{
    public interface IOpenAccessBaseRepository<TEntity, TContext>
        where TContext : OpenAccessContext, new()
    {
        IQueryable<TEntity> GetAll();
        TEntity GetBy(Expression<Func<TEntity, bool>> filter);
        TEntity AddNew(TEntity entity);
        TEntity Update(TEntity entity);
        void Delete(TEntity entity);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Telerik.OpenAccess;
using Telerik.OpenAccess.FetchOptimization;

namespace SofiaCarRentalWebApp
{
    public abstract partial class OpenAccessBaseRepository<TEntity, TContext> : 
        IOpenAccessBaseRepository<TEntity, TContext>
        where TContext : OpenAccessContext, new()
    {
        protected TContext dataContext = new TContext();
        protected FetchStrategy fetchStrategy = new FetchStrategy();

        public virtual IQueryable<TEntity> GetAll()
        {
            List<TEntity> allEntities = dataContext.
                GetAll<TEntity>().ToList();

            List<TEntity> detachedEntities = dataContext.
                CreateDetachedCopy<List<TEntity>>(allEntities, fetchStrategy);

            return detachedEntities.AsQueryable();
        }

        public virtual TEntity GetBy(Expression<Func<TEntity, bool>> filter)
        {
            if (filter == null)
                throw new ArgumentNullException("filter");

            TEntity entity = dataContext.GetAll<TEntity>().
                SingleOrDefault(filter);
            if (entity == null)
                return default(TEntity);

            TEntity detachedEntity = dataContext.
                CreateDetachedCopy(entity, fetchStrategy);

            return detachedEntity;
        }

        public virtual TEntity AddNew(TEntity entity)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            TEntity attachedEntity = dataContext.AttachCopy(entity);
            dataContext.SaveChanges();
            TEntity detachedEntity = dataContext.
                CreateDetachedCopy(attachedEntity, fetchStrategy);

            return detachedEntity;
        }

        public virtual TEntity Update(TEntity entity)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            TEntity attachedEntity = dataContext.AttachCopy(entity);
            dataContext.SaveChanges();
            TEntity detachedEntity = dataContext.
                CreateDetachedCopy(attachedEntity, fetchStrategy);

            return detachedEntity;
        }

        public virtual void Delete(TEntity entity)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            TEntity attachedEntity = dataContext.AttachCopy(entity);
            dataContext.Delete(attachedEntity);
            dataContext.SaveChanges();
        }
    }
}
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Telerik.OpenAccess;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    public partial class CarRepository : 
        OpenAccessBaseRepository<Car, FluentModel>
    { }

    public partial class CategoryRepository : 
        OpenAccessBaseRepository<Category, FluentModel>
    { }

    public partial class CustomerRepository : 
        OpenAccessBaseRepository<Customer, FluentModel>
    { }

    public partial class EmployeeRepository : 
        OpenAccessBaseRepository<Employee, FluentModel>
    { }

    public partial class RentalOrderRepository : 
        OpenAccessBaseRepository<RentalOrder, FluentModel>
    { }

    public partial class RentalRateRepository : 
        OpenAccessBaseRepository<RentalRate, FluentModel>
    { }
}

Expose The Context Through The Repository Pattern VB

  1. In the SofiaCarRentalWebApp project, add a new class file called IOpenAccessBaseRepository.
  2. Paste the code of IOpenAccessBaseRepository in the newly added file.
  3. Do the same for the OpenAccessBaseRepository class. Its code is available in the BaseRepository tab below.
  4. Add a new class file called FluentModelRepositories and in it paste the code for the entity specific repositories. It is available in the Repositories tab below.
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Linq.Expressions
Imports Telerik.OpenAccess
Imports Telerik.OpenAccess.FetchOptimization

Namespace SofiaCarRentalWebApp

    Public Interface IOpenAccessBaseRepository(Of TEntity,
        TContext As {OpenAccessContext, New})

        Function GetAll() As IQueryable(Of TEntity)
        Function GetBy(filter As Expression(Of Func(Of TEntity, Boolean))) As  _
            TEntity
        Function AddNew(entity As TEntity) As TEntity
        Function Update(entity As TEntity) As TEntity
        Sub Delete(entity As TEntity)

    End Interface

End Namespace
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Linq.Expressions
Imports Telerik.OpenAccess
Imports Telerik.OpenAccess.FetchOptimization

Namespace SofiaCarRentalWebApp

    Partial Public MustInherit Class OpenAccessBaseRepository(Of TEntity,
        TContext As {OpenAccessContext, New})
        Implements IOpenAccessBaseRepository(Of TEntity, TContext)

        Protected dataContext As New TContext()
        Protected fetchStrategy As New FetchStrategy()

        Public Overridable Function GetAll() As IQueryable(Of TEntity) _
            Implements IOpenAccessBaseRepository(Of TEntity, TContext).GetAll
            Dim allEntities As List(Of TEntity) = dataContext.
                GetAll(Of TEntity)().ToList()

            Dim detachedEntities As List(Of TEntity) = dataContext.
                CreateDetachedCopy(Of List(Of TEntity))(allEntities,
                                                        fetchStrategy)

            Return detachedEntities.AsQueryable()
        End Function

        Public Overridable Function GetBy(filter As  _
            Expression(Of Func(Of TEntity, Boolean))) As TEntity _
            Implements IOpenAccessBaseRepository(Of TEntity, TContext).GetBy
            If filter Is Nothing Then
                Throw New ArgumentNullException("filter")
            End If

            Dim entity As TEntity = dataContext.GetAll(Of TEntity)().
                SingleOrDefault(filter)
            If entity Is Nothing Then
                Return Nothing
            End If

            Dim detachedEntity As TEntity = dataContext.
                CreateDetachedCopy(entity, fetchStrategy)

            Return detachedEntity
        End Function

        Public Overridable Function AddNew(entity As TEntity) As TEntity _
            Implements IOpenAccessBaseRepository(Of TEntity, TContext).AddNew
            If entity Is Nothing Then
                Throw New ArgumentNullException("entity")
            End If

            Dim attachedEntity As TEntity = dataContext.AttachCopy(entity)
            dataContext.SaveChanges()
            Dim detachedEntity As TEntity = dataContext.
                CreateDetachedCopy(attachedEntity, fetchStrategy)

            Return detachedEntity
        End Function

        Public Overridable Function Update(entity As TEntity) As TEntity _
            Implements IOpenAccessBaseRepository(Of TEntity, TContext).Update
            If entity Is Nothing Then
                Throw New ArgumentNullException("entity")
            End If

            Dim attachedEntity As TEntity = dataContext.AttachCopy(entity)
            dataContext.SaveChanges()
            Dim detachedEntity As TEntity = dataContext.
                CreateDetachedCopy(attachedEntity, fetchStrategy)

            Return detachedEntity
        End Function

        Public Overridable Sub Delete(entity As TEntity) _
            Implements IOpenAccessBaseRepository(Of TEntity, TContext).Delete
            If entity Is Nothing Then
                Throw New ArgumentNullException("entity")
            End If

            Dim attachedEntity As TEntity = dataContext.AttachCopy(entity)
            dataContext.Delete(attachedEntity)
            dataContext.SaveChanges()
        End Sub

    End Class

End Namespace
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    Partial Public Class CarRepository
        Inherits OpenAccessBaseRepository(Of Car, FluentModel)
    End Class

        Partial Public Class CategoryRepository
        Inherits OpenAccessBaseRepository(Of Category, FluentModel)
    End Class

        Partial Public Class CustomerRepository
        Inherits OpenAccessBaseRepository(Of Customer, FluentModel)
    End Class

        Partial Public Class EmployeeRepository
        Inherits OpenAccessBaseRepository(Of Employee, FluentModel)
    End Class

        Partial Public Class RentalOrderRepository
        Inherits OpenAccessBaseRepository(Of RentalOrder, FluentModel)
    End Class

        Partial Public Class RentalRateRepository
        Inherits OpenAccessBaseRepository(Of RentalRate, FluentModel)
    End Class

End Namespace

Web API Controllers C#

  1. In the SofiaCarRentalWebApp project, add a new class file called OpenAccessBaseApiController.
  2. Paste the code of OpenAccessBaseApiController in the newly added file.
  3. Do the same for the CarsController, CategoriesController, CustomersController, EmployeesController, RentalOrdersController, and RentalRatesController classes. Their code is available in the Cars, Categories, Customers, Employees, RentalOrders, and RentalRates tabs below.
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Linq;
using Telerik.OpenAccess;

namespace SofiaCarRentalWebApp
{
    public abstract partial class 
        OpenAccessBaseApiController<TEntity, TContext> : ApiController
        where TContext : OpenAccessContext, new()
    {
        protected IOpenAccessBaseRepository<TEntity, TContext> repository;

        public virtual IQueryable<TEntity> Get()
        {
            var allEntities = repository.GetAll();

            return allEntities;
        }

        /// <summary>
        /// Creates a new entity based on the provided data
        /// </summary>
        /// <param name="entity">The new entity to be created</param>
        /// <returns>HTTP Status:
        /// - Accepted when operation is successful or 
        /// - MethodNotAllowed if the operation is disabled for this entity or
        /// - BadRequest if the provided entity is NULL</returns>
        public virtual HttpResponseMessage Post(TEntity entity)
        {
            if (entity == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            //TODO: should we check if the incomming entity 
            //is not an existing one?
            TEntity newEntity = repository.AddNew(entity);

            var response = CreateResponse(HttpStatusCode.Accepted, newEntity);
            return response;
        }

        protected abstract HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, TEntity entityToEmbed);
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for Cars entity defined in 
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class CarsController : 
        OpenAccessBaseApiController<Car, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public CarsController()
        {
            this.repository = new CarRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public CarsController
            (IOpenAccessBaseRepository<Car , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity 
        /// is found</returns>
        public virtual Car Get(Int32 id)
        {
            Car entity = repository.GetBy(s => s.CarID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity 
        /// with the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with the new 
        /// updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID parameter 
        /// does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation 
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, Car entity)
        {
            if (entity == null || id != entity.CarID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            Car entity = repository.GetBy(s => s.CarID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to 
            //the same URI must have the same effect as 
            //a single DELETE request. 
            // Therefore, the method should not return 
            //an error code if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client after 
        /// a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided 
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, Car entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<Car>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.CarID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for Categories entity defined in 
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class CategoriesController : 
        OpenAccessBaseApiController<Category, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public CategoriesController()
        {
            this.repository = new CategoryRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public CategoriesController
            (IOpenAccessBaseRepository<Category , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity 
        /// is found</returns>
        public virtual Category Get(Int32 id)
        {
            Category entity = repository.GetBy(s => s.CategoryID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity with
        /// the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with the 
        /// new updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID parameter 
        /// does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation 
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, Category entity)
        {
            if (entity == null || id != entity.CategoryID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
                    }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            Category entity = repository.GetBy(s => s.CategoryID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to the same URI
            //must have the same effect as a single DELETE request. 
            // Therefore, the method should not return an error code
            //if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client after 
        /// a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided 
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, Category entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<Category>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.CategoryID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for Customers entity defined in 
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class CustomersController : 
        OpenAccessBaseApiController<Customer, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public CustomersController()
        {
            this.repository = new CustomerRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public CustomersController
            (IOpenAccessBaseRepository<Customer , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity is found</returns>
        public virtual Customer Get(Int32 id)
        {
            Customer entity = repository.GetBy(s => s.CustomerID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity 
        /// with the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with the 
        /// new updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID 
        /// parameter does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation 
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, Customer entity)
        {
            if (entity == null || id != entity.CustomerID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            Customer entity = repository.GetBy(s => s.CustomerID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to the same URI
            //must have the same effect as a single DELETE request. 
            // Therefore, the method should not return an error
            //code if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client after 
        /// a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code 
        /// to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided 
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, Customer entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<Customer>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.CustomerID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for Employees entity defined in
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class EmployeesController : 
        OpenAccessBaseApiController<Employee, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public EmployeesController()
        {
            this.repository = new EmployeeRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public EmployeesController
            (IOpenAccessBaseRepository<Employee , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity is found</returns>
        public virtual SofiaCarRental.Model.Employee Get(Int32 id)
        {
            Employee entity = repository.GetBy(s => s.EmployeeID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity
        /// with the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with 
        /// the new updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID parameter 
        /// does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, Employee entity)
        {
            if (entity == null || id != entity.EmployeeID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            Employee entity = repository.GetBy(s => s.EmployeeID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to the same URI
            //must have the same effect as a single DELETE request. 
            // Therefore, the method should not return 
            //an error code if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client 
        /// after a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, Employee entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<Employee>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.EmployeeID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for RentalOrders entity defined in 
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class RentalOrdersController : 
        OpenAccessBaseApiController<RentalOrder, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public RentalOrdersController()
        {
            this.repository = new RentalOrderRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public RentalOrdersController
            (IOpenAccessBaseRepository<RentalOrder , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity is found</returns>
        public virtual RentalOrder Get(Int32 id)
        {
            RentalOrder entity = repository.GetBy(s => s.RentalOrderID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity
        /// with the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with the 
        /// new updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID parameter
        /// does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation 
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, RentalOrder entity)
        {
            if (entity == null || id != entity.RentalOrderID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            RentalOrder entity = repository.GetBy(s => s.RentalOrderID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to the same URI
            //must have the same effect as a single DELETE request. 
            // Therefore, the method should not return 
            //an error code if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client after 
        /// a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code 
        /// to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided 
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, RentalOrder entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<RentalOrder>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.RentalOrderID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SofiaCarRental.Model;

namespace SofiaCarRentalWebApp
{
    /// <summary>
    /// Web API Controller for RentalRates entity defined in 
    /// the SofiaCarRental.Model.FluentModel data model
    /// </summary>
    public partial class RentalRatesController : 
        OpenAccessBaseApiController<RentalRate, FluentModel>
    {
        /// <summary>
        /// Constructor used by the Web API infrastructure.
        /// </summary>
        public RentalRatesController()
        {
            this.repository = new RentalRateRepository();
        }

        /// <summary>
        /// Dependency Injection ready constructor.
        /// Usable also for unit testing.
        /// </summary>
        /// <remarks>Web API Infrastructure will ALWAYS 
        /// use the default constructor!</remarks>
        /// <param name="repository">Repository instance 
        /// of the specific type</param>
        public RentalRatesController
            (IOpenAccessBaseRepository<RentalRate , FluentModel> repository)
        {
            this.repository = repository;
        }

        // Get all method is implemented in the base class

        /// <summary>
        /// Gets single instance by it's primary key
        /// </summary>
        /// <param name="id">Primary key value to filter by</param>
        /// <returns>Entity instance if a matching entity is found</returns>
        public virtual RentalRate Get(Int32 id)
        {
            RentalRate entity = repository.GetBy(s => s.RentalRateID == id);

            if (entity == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return entity;
        }


        /// <summary>
        /// Updates single entity.
        /// </summary>
        /// <remarks>Replaces the whole existing entity
        /// with the provided one</remarks>
        /// <param name="id">ID of the entity to update</param>
        /// <param name="entity">Entity with the 
        /// new updated values</param>
        /// <returns>HttpStatusCode.BadRequest if ID parameter
        /// does not match the ID value of the entity,
        /// or HttpStatusCode.NoContent if the operation 
        /// was successful</returns>
        public virtual HttpResponseMessage Put(Int32 id, RentalRate entity)
        {
            if (entity == null || id != entity.RentalRateID)
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            repository.Update(entity);

            return Request.CreateResponse(HttpStatusCode.NoContent);
        }

        /// <summary>
        /// Deletes an entity by it's ID
        /// </summary>
        /// <param name="id">ID of the entity to delete</param>
        /// <returns>Always HttpStatusCode.OK</returns>
        public virtual HttpResponseMessage Delete(Int32 id)
        {
            RentalRate entity = repository.GetBy(s => s.RentalRateID == id);
            if (entity != null)
            {
                repository.Delete(entity);
            }

            // According to the HTTP specification, 
            //the DELETE method must be idempotent, 
            // meaning that several DELETE requests to the same URI
            //must have the same effect as a single DELETE request. 
            // Therefore, the method should not return an error code
            //if the product was already deleted.
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Creates the response sent back to client after 
        /// a new entity is successfully created.
        /// </summary>
        /// <param name="httpStatusCode">Status code 
        /// to return</param>
        /// <param name="entityToEmbed">Entity instance 
        /// to embed in the response</param>
        /// <returns>HttpResponseMessage with the provided 
        /// status code and object to embed</returns>
        protected override HttpResponseMessage CreateResponse
            (HttpStatusCode httpStatusCode, RentalRate entityToEmbed)
        {
            HttpResponseMessage response = Request.
                CreateResponse<RentalRate>(httpStatusCode, entityToEmbed);

            string uri = Url.Link("DefaultApi", new { id = entityToEmbed.RentalRateID });
            response.Headers.Location = new Uri(uri);

            return response;
        }
    }
}

Web API Controllers VB

  1. In the SofiaCarRentalWebApp project, add a new class file called OpenAccessBaseApiController.
  2. Paste the code of OpenAccessBaseApiController in the newly added file.
  3. Do the same for the CarsController, CategoriesController, CustomersController, EmployeesController, RentalOrdersController, and RentalRatesController classes. Their code is available in the Cars, Categories, Customers, Employees, RentalOrders, and RentalRates tabs below.
Imports System.Net
Imports System.Net.Http
Imports System.Web
Imports System.Web.Http
Imports System.Linq
Imports Telerik.OpenAccess

Namespace SofiaCarRentalWebApp

    Partial Public MustInherit Class _
        OpenAccessBaseApiController(Of TEntity, TContext As {OpenAccessContext, New})
        Inherits ApiController
        Protected repository As IOpenAccessBaseRepository(Of TEntity, TContext)

        Public Overridable Function GetAll() As IQueryable(Of TEntity)
            Dim allEntities = repository.GetAll()

            Return allEntities
        End Function

        Public Overridable Function Post(entity As TEntity) As HttpResponseMessage
            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            'TODO: should we check if the incomming entity is not an existing one?
            Dim newEntity As TEntity = repository.AddNew(entity)

            Dim response = CreateResponse(HttpStatusCode.Accepted, newEntity)
            Return response
        End Function

        Protected MustOverride Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As TEntity) As  _
            HttpResponseMessage
    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for Cars entity defined in 
    ''' the Global.SofiaCarRental.Model.FluentModel data model
    ''' </summary>
    Partial Public Class CarsController
        Inherits OpenAccessBaseApiController(Of Car, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New CarRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS 
        ''' use the default constructor!</remarks>
        ''' <param name="repository">Repository instance 
        ''' of the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of Car, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As Car

            Dim entity As Car = repository.GetBy(Function(g) g.CarID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter 
        ''' does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation 
        ''' was successful</returns>
        Public Overridable Function Put(id As Int32, entity As Car) As  _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.CarID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As  _
            HttpResponseMessage

            Dim entity As Car = repository.GetBy(Function(g) g.CarID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            ' the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI
            ' must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return 
            'an error code if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
        End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code to return</param>
        ''' <param name="entityToEmbed">Entity instance to embed in 
        ''' the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As Car) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of Car)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.CarID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for Categories entity defined in 
    ''' the Global.SofiaCarRental.Model.VB.FluentModel data model
    ''' </summary>
    Partial Public Class CategoriesController
        Inherits OpenAccessBaseApiController(Of Category, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New CategoryRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS use 
        ''' the default constructor!</remarks>
        ''' <param name="repository">Repository instance of 
        ''' the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of Category, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As Category

            Dim entity As Category = repository.GetBy(Function(g) g.CategoryID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter
        '''  does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation 
        ''' was successful</returns>
        Public Overridable Function Put(id As Int32, entity As Category) As  _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.CategoryID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As HttpResponseMessage

            Dim entity As Category = repository.GetBy(Function(g) g.CategoryID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            'the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI
            ' must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return an error code
            ' if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
        End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code to return</param>
        ''' <param name="entityToEmbed">Entity instance 
        ''' to embed in the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As Category) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of Category)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.CategoryID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for Customers entity defined in 
    ''' the Global.SofiaCarRental.Model.VB.FluentModel data model
    ''' </summary>
    Partial Public Class CustomersController
        Inherits OpenAccessBaseApiController(Of Customer, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New CustomerRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS 
        ''' use the default constructor!</remarks>
        ''' <param name="repository">Repository instance 
        ''' of the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of Customer, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As Customer

            Dim entity As Customer = repository.GetBy(Function(g) g.CustomerID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter 
        ''' does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation 
        ''' was successful</returns>
        Public Overridable Function Put(id As Int32, entity As Customer) As  _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.CustomerID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As HttpResponseMessage

            Dim entity As Customer = repository.GetBy(Function(g) g.CustomerID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            'the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI 
            'must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return an error code 
            'if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
        End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code 
        ''' to return</param>
        ''' <param name="entityToEmbed">Entity instance 
        ''' to embed in the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As Customer) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of Customer)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.CustomerID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for Employees entity defined in 
    ''' Global.SofiaCarRental.Model.VB.FluentModel data model
    ''' </summary>
    Partial Public Class EmployeesController
        Inherits OpenAccessBaseApiController(Of Employee, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New EmployeeRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS 
        ''' use the default constructor!</remarks>
        ''' <param name="repository">Repository instance 
        ''' of the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of Employee, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As Employee

            Dim entity As Employee = repository.GetBy(Function(g) g.EmployeeID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter 
        ''' does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation 
        ''' was successful</returns>
        Public Overridable Function Put(id As Int32, entity As Employee) As  _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.EmployeeID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As HttpResponseMessage

            Dim entity As Employee = repository.GetBy(Function(g) g.EmployeeID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            'the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI
            ' must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return an error code 
            'if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
        End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code to return</param>
        ''' <param name="entityToEmbed">Entity instance to embed 
        ''' in the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As Employee) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of Employee)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.EmployeeID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for RentalOrders entity defined in 
    ''' Global.SofiaCarRental.Model.VB.FluentModel data model
    ''' </summary>
    Partial Public Class RentalOrdersController
        Inherits OpenAccessBaseApiController(Of RentalOrder, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New RentalOrderRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS 
        ''' use the default constructor!</remarks>
        ''' <param name="repository">Repository instance 
        ''' of the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of RentalOrder, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As RentalOrder

            Dim entity As RentalOrder = repository.GetBy(Function(g) g.RentalOrderID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter
        '''  does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation 
        ''' was successful</returns>
        Public Overridable Function Put(id As Int32, entity As RentalOrder) As _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.RentalOrderID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As HttpResponseMessage

            Dim entity As RentalOrder = repository.GetBy(Function(g) g.RentalOrderID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            'the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI 
            'must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return an error code 
            'if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
        End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code 
        ''' to return</param>
        ''' <param name="entityToEmbed">Entity instance 
        ''' to embed in the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As RentalOrder) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of RentalOrder)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.RentalOrderID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace
Imports System
Imports System.Net
Imports System.Net.Http
Imports System.Web.Http
Imports SofiaCarRental.Model

Namespace SofiaCarRentalWebApp

    ''' <summary>
    ''' Web API Controller for RentalRates entity defined in 
    ''' Global.SofiaCarRental.Model.VB.FluentModel data model
    ''' </summary>
    Partial Public Class RentalRatesController
        Inherits OpenAccessBaseApiController(Of RentalRate, FluentModel)

        ''' <summary>
        ''' Constructor used by the Web API infrastructure.
        ''' </summary>
        Public Sub New()
            Me.repository = New RentalRateRepository()
        End Sub

        ''' <summary>
        ''' Dependency Injection ready constructor.
        ''' Usable also for unit testing.
        ''' </summary>
        ''' <remarks>Web API Infrastructure will ALWAYS 
        ''' use the default constructor!</remarks>
        ''' <param name="repository">Repository instance 
        ''' of the specific type</param>
        Public Sub New(repository As  _
                       IOpenAccessBaseRepository(Of RentalRate, FluentModel))
            Me.repository = repository
        End Sub

        ' Get all method is implemented in the base class

        ''' <summary>
        ''' Gets single instance by it's primary key
        ''' </summary>
        ''' <param name="id">Primary key value to filter by</param>
        ''' <returns>Entity instance if a matching entity is found</returns>
        Public Overridable Function GetById(id As Int32) As RentalRate

            Dim entity As RentalRate = repository.GetBy(Function(g) g.RentalRateID = id)

            If entity Is Nothing Then
                Throw New HttpResponseException(HttpStatusCode.NotFound)
            End If

            Return entity
        End Function

        ''' <summary>
        ''' Updates single entity.
        ''' </summary>
        ''' <remarks>Replaces the whole existing entity 
        ''' with the provided one</remarks>
        ''' <param name="id">ID of the entity to update</param>
        ''' <param name="entity">Entity with the 
        ''' new updated values</param>
        ''' <returns>HttpStatusCode.BadRequest if ID parameter
        '''  does not match the ID value of the entity,
        ''' or HttpStatusCode.NoContent if the operation
        '''  was successful</returns>
        Public Overridable Function Put(id As Int32, entity As RentalRate) As  _
            HttpResponseMessage

            If entity Is Nothing OrElse id <> entity.RentalRateID Then
                Throw New HttpResponseException(HttpStatusCode.BadRequest)
            End If

            repository.Update(entity)

            Return Request.CreateResponse(HttpStatusCode.NoContent)
        End Function

        ''' <summary>
        ''' Deletes an entity by it's Id
        ''' </summary>
        ''' <param name="id">ID of the entity to delete</param>
        ''' <returns>Always HttpStatusCode.OK</returns>
        Public Overridable Function Delete(id As Int32) As HttpResponseMessage

            Dim entity As RentalRate = repository.GetBy(Function(g) g.RentalRateID = id)
            If entity IsNot Nothing Then
                repository.Delete(entity)
            End If

            ' According to the HTTP specification, 
            'the DELETE method must be idempotent, 
            ' meaning that several DELETE requests to the same URI
            ' must have the same effect as a single DELETE request. 
            ' Therefore, the method should not return 
            'an error code if the product was already deleted.
            Return New HttpResponseMessage(HttpStatusCode.OK)
                End Function

        ''' <summary>
        ''' Creates the response sent back to client after 
        ''' a new entity is successfully created.
        ''' </summary>
        ''' <param name="httpStatusCode">Status code 
        ''' to return</param>
        ''' <param name="entityToEmbed">Entity instance 
        ''' to embed in the response</param>
        ''' <returns>HttpResponseMessage with the provided 
        ''' status code and object to embed</returns>
        Protected Overrides Function CreateResponse _
            (httpStatusCode As HttpStatusCode, entityToEmbed As RentalRate) As  _
            HttpResponseMessage

            Dim response As HttpResponseMessage = Request.
                CreateResponse(Of RentalRate)(httpStatusCode, entityToEmbed)

            Dim uri As String = Url.Link("DefaultApi", New With { _
             .id = entityToEmbed.RentalRateID _
            })
            response.Headers.Location = New Uri(uri)

            Return response
        End Function

    End Class
End Namespace