Я пытаюсь вызвать метод контроллера веб-API, который получает параметр из uri, как показано ниже:
// GET /odata/People(3)
public SingleResult<Person> Get([FromODataUri] int key)
{
return SingleResult.Create(DemoDataSources.Instance.People.Where(p => p.ID == key.ToString()).AsQueryable());
}
Приведенный выше метод не вызывается URL-адресом http://localhost:port/odata/People(3) всегда возвращает 404 Not Found.
Я с нуля настроил новое веб-приложение OData Asp.Net со следующими файлами:
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; }
}
Я «думаю», что эта проблема связана с маршрутизацией odata, но я понятия не имею, почему такое базовое поведение не работает должным образом...
Ценим любую помощь! Маркос