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.
- 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.
-
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:
- You will create the generic IOpenAccessBaseRepository interface that defines the operations,
- The OpenAccessBaseRepository class for the implementation of the necessary Data Access logic, and
-
A specific repository for each persistent class.
The code for the task is available in the Expose The Context Through The Repository Pattern C# and Expose The Context Through The Repository Pattern VB sections of this tutorial.
-
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
-
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
-
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>
-
Next, you have to add the default Web API route to the route table of the application:
- Open the Global.asax.cs(vb) file.
-
Add the following references:
using System.Web.Http; using System.Web.Routing;
Imports System.Web.Http Imports System.Web.Routing
-
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#
- In the SofiaCarRentalWebApp project, add a new class file called IOpenAccessBaseRepository.
- Paste the code of IOpenAccessBaseRepository in the newly added file.
- Do the same for the OpenAccessBaseRepository class. Its code is available in the BaseRepository tab below.
- 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
- In the SofiaCarRentalWebApp project, add a new class file called IOpenAccessBaseRepository.
- Paste the code of IOpenAccessBaseRepository in the newly added file.
- Do the same for the OpenAccessBaseRepository class. Its code is available in the BaseRepository tab below.
- 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#
- In the SofiaCarRentalWebApp project, add a new class file called OpenAccessBaseApiController.
- Paste the code of OpenAccessBaseApiController in the newly added file.
- 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
- In the SofiaCarRentalWebApp project, add a new class file called OpenAccessBaseApiController.
- Paste the code of OpenAccessBaseApiController in the newly added file.
- 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