2016-12-19 7 views
0

gefunden ich versuche‘eine Web-api OData Controller-Methode aufrufen, die einen Parameter aus dem uri erhält, wie unten:Web Api OData v4 FromODataUri immer 404 Rückkehr Nicht

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

Das obige Verfahren wird durch die nicht getroffen zu werden URL http://localhost:port/odata/People(3) immer zurück 404 nicht gefunden.

ich eine neue Asp.Net OData Web Application von Grund auf mit den folgenden Dateien konfiguriert haben:

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; } 
} 

ich "denken", dieses Problem mit OData-Routing zu tun hat, aber ich habe keine Ahnung, warum eine solche ein grundlegendes Verhalten funktioniert nicht richtig ...

Schätzen Sie jede Hilfe! Marcos

Antwort

1

Sie benötigen einfache Anführungszeichen für die ID in der Route zu verwenden, da der string Typ der Schlüsseleigenschaft der Person Klasse: http://localhost:port/odata/People (‚3‘)

1

Im Fall, dass Sie einen String-Wert übergeben Wie von Andriy vorgeschlagen, müssen Sie wahrscheinlich auch die Signatur des Get ändern.

So ändern: öffentlichen SingleResult Get ([FromODataUri] int key)

An: öffentlichen SingleResult Get ([FromODataUri] string key)

Und dann denke ich Ihnen den OData-Dienst aufrufen können als vorgeschlagen von Andriy.