WebAPI OData – 10 min video introduction (Visual Studio 2013)
I’ve been learning about OData and wanted to record a quick getting started video with how to create a new WebAPI project, add OData Controller, and send HTTP CRUD operations. Below is an example using Adventure Works Departments with sample code, screenshots, and a 10 minute video introduction. Please leave a comment if you found this helpful. Thanks! ![]()
Video Content
- Create MVC 4 web application
- SQL Express – Adventure Works Departments
- Add “AdventureWorks.edmx”
- Wizard driven
- F4 set namespace
- Add “DepartmentsController.cs”
- Create from EDMX class
- Implements ODataController
- Replace ID with KEY
- Edit “WebApiConfig.cs”
- Comment out default route
- Add OData route builder
- Test with HTTP manually
- Test with Chrome REST Postman
- SQL Express – see changed data
Watch Video
WebAPI OData – 10 min video introduction (Visual Studio 2013) from Jeff Jones on Vimeo.
Sample Code
[WebApiConfig.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.OData.Builder;
namespace MvcApplication1
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
ODataConventionModelBuilder build = new ODataConventionModelBuilder();
build.EntitySet("Departments");
config.Routes.MapODataRoute("odata", "odata", build.GetEdmModel());
config.EnableQuerySupport(new QueryableAttribute());
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
}
[DepartmentsController.cs]
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Http.OData;
namespace MvcApplication1.Controllers
{
public class DepartmentsController : ODataController
{
private AdventureWorks2012Entities db = new AdventureWorks2012Entities();
// GET api/Default1
public IEnumerable GetDepartments()
{
return db.Departments.AsEnumerable();
}
// GET api/Default1/5
public Department GetDepartment(short key)
{
Department department = db.Departments.Find(key);
if (department == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return department;
}
// PUT api/Default1/5
public HttpResponseMessage PutDepartment(short key, Department department)
{
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
if (key != department.DepartmentID)
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
db.Entry(department).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
// POST api/Default1
public HttpResponseMessage PostDepartment(Department department)
{
if (ModelState.IsValid)
{
db.Departments.Add(department);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, department);
response.Headers.Location = new Uri(Url.Link("odata", new { key = department.DepartmentID }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
// DELETE api/Default1/5
public HttpResponseMessage DeleteDepartment(short key)
{
Department department = db.Departments.Find(key);
if (department == null)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
db.Departments.Remove(department);
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
}
return Request.CreateResponse(HttpStatusCode.OK, department);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}
}

Hi Jeff,
i have followed your walk through to the letter, but I am experiencing an issue with accessing the entity.
I can see the localhost:12345/odata and localhost:12345/odata/$metadata pages, but the localhost:12345/MYEntity results in displaying “Server Error in ‘/’ Application” error.
I am a complete newbie, so it is quite possible i have missed out some basic prerequisites. Could you think of something obvious from top of your head or point me to some resources?
Kind regards
sorry, just noticed that the sentence should have been:
but the localhost:12345/odata/MYEntity results in displaying “Server Error in ‘/’ Application” error.