title: Pass Parameters in OData WebApi Url
body: <p>Using Web Api I have an OData EndPoint which can return Products from a database.</p>
  
  <p>I have multiple databases with similar schemas, and want to pass a parameter in the URL to identify which database the Api should use.</p>
  
  <p><strong>Current Odata Endpoint:</strong><br>
  <a href="http://localhost:62999/Products" rel="nofollow noreferrer">http://localhost:62999/Products</a></p>
  
  <p><strong>What I want:</strong><br>
  <a href="http://localhost:62999/" rel="nofollow noreferrer">http://localhost:62999/</a><strong>999</strong>/Products</p>
  
  <p>In the new Url, I pass in 999 (the database ID).</p>
  
  <p>The database ID is intended to specify which database to load the product from.  For example <code>localhost:62999/999/Products('ABC123')</code> would load product 'ABC123' from database 999, but the next request, <code>localhost:62999/111/Products('XYZ789')</code> would load the product 'XYZ789' from database 111.</p>
  
  <p>The Url below works, but I don't like it.<br>
  <code>localhost:62999/Products('XYZ789')?database=111</code> </p>
  
  <p>Here is the code for the controller:</p>
  
  <pre><code>public class ProductsController : ErpApiController //extends ODataController, handles disposing of database resources
  {
      public ProductsController(IErpService erpService) : base(erpService) { }
  
      [EnableQuery(PageSize = 50)]
      public IQueryable&lt;ProductDto&gt; Get(ODataQueryOptions&lt;ProductDto&gt; queryOptions)
      {
          return ErpService.Products(queryOptions);
      }
  
      [EnableQuery]
      public SingleResult&lt;ProductDto&gt; Get([FromODataUri] string key, ODataQueryOptions&lt;ProductDto&gt; queryOptions)
      {
          var result = ErpService.Products(queryOptions).Where(p =&gt; p.StockCode == key);
          return SingleResult.Create(result);
      }               
  }
  </code></pre>
  
  <p>I use Ninject to resolve which implementation of IErpService to inject into the controller by binding to a service provider:</p>
  
  <p><code>kernel.Bind&lt;IErpService&gt;().ToProvider(new ErpServiceProvider());</code>
   And the <code>ErpServiceProvider</code> inspects the url to identify the databaseId required by this request:</p>
  
  <pre><code>public class ErpServiceProvider : Provider&lt;IErpService&gt;
  {
      protected override IErpService CreateInstance(IContext context)
      {
          var databaseId = HttpContext.Current.Request["database"];
  
          return new SageErpService(new SageContext(GetDbConnection(databaseId)));
      }
  }
  </code></pre>
  
  <p>The bit I am stuck on is how to define the Url parameter in the OData route config.</p>
  
  <p>Normal WebApi routes can have parameters defined as follows:</p>
  
  <pre><code>config.Routes.MapHttpRoute(
              name: "DefaultApi",
              routeTemplate: "api/{controller}/{id}",
              defaults: new { id = RouteParameter.Optional }
        );
  </code></pre>
  
  <p>But how do I define the parameters in the OData route config?</p>
  
  <pre><code>ODataModelBuilder builder = new ODataConventionModelBuilder();
          builder.EntitySet&lt;ProductDto&gt;("Products");
          builder.EntitySet&lt;WorkOrderDto&gt;("WorkOrders");
          config.MapODataServiceRoute(
              routeName: "ODataRoute",
              routePrefix: null,
              model: builder.GetEdmModel());
  </code></pre>
  
  <p>Is this even where I should be defining the Url parameters?
  I have also thought about using a Message Handler but I am not certain how this can be implemented either.</p>
  
  <p><strong>UPDATE</strong><br>
  This question is trying to do the same thing as me: <a href="https://stackoverflow.com/questions/27827188/how-to-decalre-a-parameter-as-prefix-on-odata">How to declare a parameter as prefix on OData</a>
  <br>
  But it is not clear how the parameter is to be read from the url. <br>
  <code>var databaseId = HttpContext.Current.Request["database"];</code> returns null currently.<br> Even after updating the route config to the following:</p>
  
  <pre><code>public static void Register(HttpConfiguration config)
  {
      // Web API routes
      config.MapHttpAttributeRoutes();
  
      config.Routes.MapHttpRoute(
          name: "ErpApi",
          routeTemplate: "{database}/{controller}"                
      );
  
      // Web API configuration and services
      ODataModelBuilder builder = new ODataConventionModelBuilder();
      builder.EntitySet&lt;ProductDto&gt;("Products");
      builder.EntitySet&lt;WorkOrderDto&gt;("WorkOrders");
      config.MapODataServiceRoute(
          routeName: "ODataRoute",
          routePrefix: "{company}/",
          model: builder.GetEdmModel());
  
      config.Routes.MapHttpRoute(
          name: "DefaultApi",
          routeTemplate: "api/{controller}/{id}",
          defaults: new { id = RouteParameter.Optional }
      );
  }
  </code></pre>