title: ASP.Net Core + EF + OData V4 Core Beta 2
body: <p>Have a fairly basic Web API project on ASP.NET Core configured with EF which was working okay with Web API. I was following <a href="http://azurecoder.net/2018/02/19/creating-odata-api-asp-net-core-2-0/" rel="nofollow noreferrer">this</a> article to convert to use Odata and I can't quite get it to work.</p>
  
  <p>I have a parent object called customer with 2x child objects: Addresses and Person. I have seeded the database so I can see there is data there, and the Odata endpoint looks good because when you start the project it displays the entities and odata/$metadata displays the EDM structure as expected.</p>
  
  <p>The only issue I have currently is that when I navigate to a URL, such as /odata/customers, I receive a blank screen. In postman it returns 404.</p>
  
  <p>I've combed through the example project from Lucas (the article I was following) and reseached a fair bit online and can't quite see what I'm doing wrong.</p>
  
  <p>I'm sure it's something simple/silly, but any constructive guidance welcomed :)</p>
  
  <p>** Edit ** Removed additional code for simplicity (and based on feedback). Let me know if additional information is required.</p>
  
  <p>Cheers,</p>
  
  <p>Adam</p>
  
  <p>File Path: Odata\BookingsModelBuilder.cs</p>
  
  <pre><code>using System;
  using Microsoft.AspNet.OData.Builder;
  using Microsoft.OData.Edm;
  using Bookings_Server.OData.Models;
  
  
  namespace Bookings_Server
  {
      public class BookingsModelBuilder
      {
          public IEdmModel GetEdmModel(IServiceProvider serviceProvider)
          {
              var builder = new ODataConventionModelBuilder(serviceProvider);
  
              builder.EntitySet&lt;Address&gt;("addresses")
                             .EntityType
                             .Filter() // Allow for the $filter Command
                             .Count() // Allow for the $count Command
                             .Expand() // Allow for the $expand Command
                             .OrderBy() // Allow for the $orderby Command
                             .Page() // Allow for the $top and $skip Commands
                             .Select();// Allow for the $select Command; 
  
              builder.EntitySet&lt;Customer&gt;("customers")
                             .EntityType
                             .Filter() // Allow for the $filter Command
                             .Count() // Allow for the $count Command
                             .Expand() // Allow for the $expand Command
                             .OrderBy() // Allow for the $orderby Command
                             .Page() // Allow for the $top and $skip Commands
                             .Select();// Allow for the $select Command; 
  
              builder.EntitySet&lt;Person&gt;("people")
                              .EntityType
                              .Filter() // Allow for the $filter Command
                              .Count() // Allow for the $count Command
                              .Expand() // Allow for the $expand Command
                              .OrderBy() // Allow for the $orderby Command
                              .Page() // Allow for the $top and $skip Commands
                              .Select();// Allow for the $select Command; 
  
              return builder.GetEdmModel();
          }
      }
  }
  </code></pre>
  
  <p>File path: EF\DataContext.CS</p>
  
  <pre><code>using Microsoft.EntityFrameworkCore;
  using Bookings_Server.OData.Models;
  
  namespace Bookings_Server.EF
  {
      public class DataContext : DbContext
      {
          public DataContext(DbContextOptions&lt;DataContext&gt; options) : base(options) { }
  
          public DbSet&lt;Address&gt; Addresses { get; set; }
          public DbSet&lt;Customer&gt; Customers { get; set; }
          public DbSet&lt;Person&gt; People { get; set; }
          public DbSet&lt;Tenant&gt; Tenants { get; set; }
      }
  }
  </code></pre>
  
  <p>File path: Controllers\CustomersController.cs</p>
  
  <pre><code>using System.Linq;
  using Microsoft.AspNetCore.Mvc;
  using Bookings_Server.EF;
  using Bookings_Server.OData.Models;
  using Microsoft.AspNet.OData;
  
  
  namespace Bookings_Server.OData.Controllers
  {
      [Produces("application/json")]
      public class CustomersController : ODataController
      {
          private readonly DataContext _context;
  
          public CustomersController(DataContext context)
          {
              _context = context;
          }
  
          // GET: odata/customers
          [EnableQuery(PageSize = 20)]       
          public IQueryable&lt;Customer&gt; Get() =&gt; _context.Customers.AsQueryable();
  
          /*
          public IActionResult Get()
          {
              return Ok(_context.Customers.AsQueryable());
          }
          */
      }
  }
  </code></pre>
  
  <p>File path: startup.cs</p>
  
  <pre><code>using System;
  using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.EntityFrameworkCore;
  using Microsoft.AspNet.OData.Extensions;
  using Newtonsoft.Json;
  using Newtonsoft.Json.Serialization;
  
  namespace Bookings_Server
  {
      public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
  
          public IConfiguration Configuration { get; }
  
  
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IHostingEnvironment env, BookingsModelBuilder BookingsModelBuilder)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
  
              app.UseCors("cors");
              // app.UseMvc();
  
              // Added for Odata config
              app.UseMvc(routeBuilder =&gt;
              {
                  routeBuilder.MapODataServiceRoute("ODataRoutes", "odata", BookingsModelBuilder.GetEdmModel(app.ApplicationServices));
              });
  
          }
  
          // This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
              services.AddCors(options =&gt; options.AddPolicy("cors", builder =&gt;
              {
                  builder
                  .AllowAnyOrigin()
                  .AllowAnyMethod()
                  .AllowAnyHeader();
              }
  
              ));
              var connection = @"Server=(localdb)\mssqllocaldb;Database=BookingsDB;Trusted_Connection=True;";
              services.AddDbContext&lt;EF.DataContext&gt;(options =&gt; options.UseSqlServer(connection));
  
              // Add OData configuration
              services.AddOData();
              services.AddTransient&lt;BookingsModelBuilder&gt;();
  
              services.AddMvc().AddJsonOptions(opt =&gt;
              {
                  opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                  opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
              });
  
          }
      }
  }
  </code></pre>