2016-12-19 1 views
0

I » essayer invoquer une api web méthode du contrôleur OData qui reçoit un paramètre du uri, comme ci-dessous:Web Api OData de FromODataUri toujours retour 404 Not Found

// GET /odata/People(3) 
    public SingleResult<Person> Get([FromODataUri] int key) 
    { 
     return SingleResult.Create(DemoDataSources.Instance.People.Where(p => p.ID == key.ToString()).AsQueryable()); 
    } 

La méthode ci-dessus n'est pas touché par la url http://localhost:port/odata/People(3) retourne toujours 404 introuvable.

J'ai configuré une nouvelle application Web Asp.Net OData à partir de zéro avec les fichiers suivants:

PeopleController.cs

[EnableQuery] 
public class PeopleController : ODataController 
{ 

    // GET /odata/People 
    public IHttpActionResult Get() 
    { 
     return Ok(DemoDataSources.Instance.People.AsQueryable()); 
    } 

    // GET /odata/People(3) 
    public SingleResult<Person> Get([FromODataUri] int key) 
    { 
     return SingleResult.Create(DemoDataSources.Instance.People.Where(p => p.ID == key.ToString()).AsQueryable()); 
    } 
} 

WebApiConfig.cs

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // Web API configuration and services 
     // Configure Web API to use only bearer token authentication. 
     config.SuppressDefaultHostAuthentication(); 
     config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 

     // Web API routes 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

     config.MapODataServiceRoute("odata", "odata", GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer)); 
     config.EnsureInitialized(); 
    } 

    private static IEdmModel GetEdmModel() 
    { 
     ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); 
     builder.Namespace = "Demos"; 
     builder.ContainerName = "DefaultContainer"; 
     builder.EntitySet<Person>("People"); 
     builder.EntitySet<Trip>("Trips"); 
     var edmModel = builder.GetEdmModel(); 
     return edmModel; 
    } 
} 

DemoDataSources.cs

public class DemoDataSources 
{ 
    private static DemoDataSources instance = null; 
    public static DemoDataSources Instance 
    { 
     get 
     { 
      if (instance == null) 
      { 
       instance = new DemoDataSources(); 
      } 
      return instance; 
     } 
    } 
    public List<Person> People { get; set; } 
    public List<Trip> Trips { get; set; } 
    private DemoDataSources() 
    { 
     this.Reset(); 
     this.Initialize(); 
    } 
    public void Reset() 
    { 
     this.People = new List<Person>(); 
     this.Trips = new List<Trip>(); 
    } 
    public void Initialize() 
    { 
     this.Trips.AddRange(new List<Trip>() 
     { 
      new Trip() 
      { 
       ID = "0", 
       Name = "Trip 0" 
      }, 
      new Trip() 
      { 
       ID = "1", 
       Name = "Trip 1" 
      }, 
      new Trip() 
      { 
       ID = "2", 
       Name = "Trip 2" 
      }, 
      new Trip() 
      { 
       ID = "3", 
       Name = "Trip 3" 
      } 
     }); 
     this.People.AddRange(new List<Person> 
     { 
      new Person() 
      { 
       ID = "001", 
       Name = "Angel", 
       Trips = new List<Trip>{Trips[0], Trips[1]} 
      }, 
      new Person() 
      { 
       ID = "002", 
       Name = "Clyde", 
       Description = "Contrary to popular belief, Lorem Ipsum is not simply random text.", 
       Trips = new List<Trip>{Trips[2], Trips[3]} 
      }, 
      new Person() 
      { 
       ID = "003", 
       Name = "Elaine", 
       Description = "It has roots in a piece of classical Latin literature from 45 BC, making Lorems over 2000 years old." 
      } 
     }); 
    } 
} 

Person.cs

public class Person 
{ 
    [Key] 
    public String ID { get; set; } 
    [Required] 
    public String Name { get; set; } 
    public String Description { get; set; } 
    public List<Trip> Trips { get; set; } 
} 

Trip.cs

public class Trip 
{ 
    [Key] 
    public String ID { get; set; } 
    [Required] 
    public String Name { get; set; } 
} 

I "pense" ce problème a à voir avec le routage OData mais je n'ai aucune idée pourquoi une telle un comportement de base ne fonctionne pas correctement ...

Appréciez toute aide! Marcos

Répondre

1

Vous devez utiliser des guillemets simples pour l'id dans la route à cause du type string de la propriété clé de la classe Person: http://localhost:port/odata/People (« 3 »)

1

Dans le cas vous passez une valeur de chaîne comme suggéré par Andriy, vous devez probablement changer la signature du get aussi.

changer donc: SingleResult publique Get ([FromODataUri] clé int)

Pour: publique SingleResult Get ([FromODataUri] touche string)

Et puis je pense que vous pouvez appeler le service OData comme suggéré par Andriy.