2015-04-30 12 views
5

Sto costruendo un servizio OData 3 su Web API 2.2.ODataController restituisce HTTP 406 non accettabile

Il servizio restituisce correttamente i metadati per le mie entità, ma restituisce 406 Not Available quando interrogo una delle entità effettive. Ho fatto un bel po 'di ricerche (attualmente sto seguendo diversi tutorial), ma non ho trovato nulla che funzioni effettivamente.

Ecco la mia WebApiConfig:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Http; 
using System.Web.OData.Builder; 
using System.Web.OData.Extensions; 

namespace MyProject 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      ODataModelBuilder builder = new ODataConventionModelBuilder(); 

      builder.EntitySet<MarvelCharacter>("MarvelCharacters"); 
      config.MapODataServiceRoute(
       routeName: "Marvel", 
       routePrefix: "dude", 
       model: builder.GetEdmModel()); 
     } 
    } 
} 

E mio controller (non completo, ma si ottiene l'idea):

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using System.Web.Http.OData; 
using System.Web.Http.OData.Query; 
using Microsoft.Data.OData; 
using MyProject; 

namespace MyProject.Controllers 
{ 
    public class MarvelCharactersController : ODataController 
    { 
     private static ODataValidationSettings _validationSettings = new ODataValidationSettings(); 

     // GET: odata/MarvelCharacters 
     public IHttpActionResult GetMarvelCharacters(ODataQueryOptions<MarvelCharacter> queryOptions) 
     { 
      // validate the query. 
      try 
      { 
       queryOptions.Validate(_validationSettings); 
      } 
      catch (ODataException ex) 
      { 
       return BadRequest(ex.Message); 
      } 

      var entities = new myEntities(); 
      var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList(); 

      return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters); 
     } 
    } 
} 

risposta

18

Si scopre che la risposta a questo è stato piuttosto semplice, ma non è stato trattato bene da alcuna documentazione che ho trovato.

Stavo cercando di implementare un endpoint OData 3 su WebAPI 2.2. Stavo seguendo diversi tutorial, alcuni per OData 3 e alcuni per OData 4.

Stavo usando OData 4 (System.Web.OData) nel mio WebApiConfig e OData 3 (System.Web.Http.OData) nel mio controller. Risulta, non giocano bene insieme.

Ho deciso di inviare la risposta qui nel caso in cui qualcun altro abbia un problema simile.

Per aggiungere un piccolo valore, e dal momento che stavo mixando entrambi, ho deciso di andare avanti e impostare il supporto per entrambe le versioni 3 e 4 facendo l'aliasing degli spazi dei nomi nel mio WebApiConfig e quindi creando controller con versioni.

WebApiConfig:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web.Http; 
using ODataV3 = System.Web.Http.OData; 
using ODataV4 = System.Web.OData; 

namespace MyProject 
{ 
    public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      // OData V3 Route 

      ODataV3.Builder.ODataModelBuilder builder3 = new ODataV3.Builder.ODataConventionModelBuilder(); 

      builder3.EntitySet<MarvelCharacter>("MarvelCharactersV3"); 
      // The MapODataRoute function is deprecated in WebAPI 2.2, 
      // but I haven't found an alternative for supporting OData 3. 
      config.Routes.MapODataRoute(
       routeName: "Marvel3", 
       routePrefix: "dude3", 
       model: builder3.GetEdmModel()); 

      // ODate V4 Route 

      ODataV4.Builder.ODataModelBuilder builder4 = new ODataV4.Builder.ODataConventionModelBuilder(); 

      builder4.EntitySet<MarvelCharacter>("MarvelCharactersV4"); 
      ODataV4.Extensions.HttpConfigurationExtensions.MapODataServiceRoute(
       configuration: config, 
       routeName: "Marvel4", 
       routePrefix: "dude4", 
       model: builder4.GetEdmModel()); 
     } 
    } 
} 

MarvelCharactersV3 (OData 3):

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using System.Web.Http.OData; // OData V3 
using System.Web.Http.OData.Query; 
using Microsoft.Data.OData; 
using MyProject; 

namespace MyProject.Controllers 
{ 
    public class MarvelCharactersV3Controller : ODataController 
    { 
     private static ODataValidationSettings _validationSettings = new ODataValidationSettings(); 

     // GET: odata/MarvelCharacters 
     public IHttpActionResult GetMarvelCharactersV3(ODataQueryOptions<MarvelCharacter> queryOptions) 
     { 
      // validate the query. 
      try 
      { 
       queryOptions.Validate(_validationSettings); 
      } 
      catch (ODataException ex) 
      { 
       return BadRequest(ex.Message); 
      } 

      var entities = new myEntities(); 
      var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList(); 

      return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters); 
     } 
    } 
} 

MarvelCharactersV4 (OData 4):

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using System.Web.OData; // OData 4 
using System.Web.OData.Query; 
using Microsoft.Data.OData; 
using MyProject; 

namespace MyProject.Controllers 
{ 
    public class MarvelCharactersV4Controller : ODataController 
    { 
     private static ODataValidationSettings _validationSettings = new ODataValidationSettings(); 

     // GET: odata/MarvelCharacters 
     public IHttpActionResult GetMarvelCharactersV4(ODataQueryOptions<MarvelCharacter> queryOptions) 
     { 
      // validate the query. 
      try 
      { 
       queryOptions.Validate(_validationSettings); 
      } 
      catch (ODataException ex) 
      { 
       return BadRequest(ex.Message); 
      } 

      var entities = new myEntities(); 
      var marvelCharacters = (from c in entities.MarvelCharacters select c).ToList(); 

      return Ok<IEnumerable<MarvelCharacter>>(marvelCharacters); 
     } 
    } 
} 

Non è probabilmente la migliore architettura (lo farò probabilmente creare una libreria per consolidare simi codice lar tra i controller), ma ho provato e posso interrogare con successo tramite OData 3 e OData 4, quindi sono abbastanza contento per ora.

+8

Mi auguro che Microsoft abbia effettivamente utilizzato i numeri di telefono "OdataV3" e "OdataV4" invece di inserire nuove versioni qui e là, volenti o nolenti +1 per lo pseudonimo - ottima idea – bkwdesign

+0

Ho lo stesso problema, prima configurazione con oData v3 e in seguito spostato su oData v4 e i controller creati con V4 iniziarono a dare errore 406. Creato un controller di nuovo con V3 per verificare il problema e si inizia a funzionare. Ora l'aggiornamento a V4 per tutti. – Zafar

+1

Grazie mille! –

Problemi correlati