Работа с ASP.NET Core и OData v4
Я получаю
InvalidOperationException: шаблон пути
'Классы ({key}) / Bookings ({bookingKey}) "по действию" GetBooking "в
Контроллер 'Классы' не является допустимым шаблоном пути OData. Неверный запрос -
Ошибка в синтаксисе запроса.
Я не вижу ошибки в синтаксисе запроса. Вот полный код этого метода в моем контроллере «Классы»
/// <summary>
/// Get a specific booking
/// </summary>
/// <returns></returns>
[HttpGet]
[ODataRoute("Classes({key})/Bookings({bookingKey})")]
public async Task<IActionResult> GetBooking([FromODataUri] Guid key, [FromODataUri] Guid bookingKey)
{
var @class = await _context.Classes.FirstOrDefaultAsync(y => y.Id == key);
if (@class == null)
{
return NotFound();
}
var booking = _context.Bookings.Where(y => y.Class.Id == key && y.Id == bookingKey);
if (!booking.Any())
{
return NotFound();
}
return Ok(SingleResult.Create(booking));
}
Этот метод определен в контроллере «Классы». У меня также есть метод GeBookings и 2 метода действий, которые не вызывают проблем. Когда я комментирую свой метод GetBooking (), у меня нет ошибок.
Бронирование - это [Содержится] ICollection of Booking
public class Class
{
[Key]
public Guid Id { get; set; }
// Others properties
[Contained]
public ICollection<Booking> Bookings {get; set;}
}
Я действительно вижу свою ошибку. Стоит ли искать?
РЕДАКТИРОВАТЬ Больше информации
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="Oyg" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Owner">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Email" Type="Edm.String" />
<Property Name="PhoneNumber" Type="Edm.String" />
<Property Name="Hash" Type="Edm.String" />
<Property Name="ConfigurationString" Type="Edm.String" />
<NavigationProperty Name="Teachers" Type="Collection(Oyg.Teacher)" ContainsTarget="true" />
<NavigationProperty Name="Locations" Type="Collection(Oyg.Location)" ContainsTarget="true" />
<NavigationProperty Name="Classes" Type="Collection(Oyg.Class)" ContainsTarget="true" />
</EntityType>
<EntityType Name="Student">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Email" Type="Edm.String" />
<Property Name="PhoneNumber" Type="Edm.String" />
<Property Name="Hash" Type="Edm.String" />
<Property Name="ConfigurationString" Type="Edm.String" />
</EntityType>
<EntityType Name="Class">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Title" Type="Edm.String" />
<Property Name="Description" Type="Edm.String" />
<Property Name="StartTime" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="EndTime" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="Status" Type="Oyg.ScheduleStatus" Nullable="false" />
<Property Name="Positions" Type="Edm.Int32" Nullable="false" />
<Property Name="Bookings" Type="Collection(Oyg.Booking)" />
<NavigationProperty Name="Owner" Type="Oyg.Owner" />
<NavigationProperty Name="Teacher" Type="Oyg.Teacher" />
<NavigationProperty Name="Location" Type="Oyg.Location" />
</EntityType>
<ComplexType Name="Booking">
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Position" Type="Edm.Int32" Nullable="false" />
<Property Name="ReservationTime" Type="Edm.DateTimeOffset" Nullable="false" />
<Property Name="CancelTime" Type="Edm.DateTimeOffset" />
<NavigationProperty Name="Class" Type="Oyg.Class" Nullable="false" />
<NavigationProperty Name="Student" Type="Oyg.Student" Nullable="false" />
</ComplexType>
<EntityType Name="Teacher">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Name" Type="Edm.String" />
<Property Name="Description" Type="Edm.String" />
<Property Name="Email" Type="Edm.String" />
<Property Name="PhoneNumber" Type="Edm.String" />
<Property Name="Website" Type="Edm.String" />
<NavigationProperty Name="Owner" Type="Oyg.Owner" />
</EntityType>
<EntityType Name="Location">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Guid" Nullable="false" />
<Property Name="Title" Type="Edm.String" />
<Property Name="Description" Type="Edm.String" />
<Property Name="Geolocalisation" Type="Edm.String" />
<Property Name="Address" Type="Edm.String" />
<Property Name="Facilities" Type="Edm.String" />
<NavigationProperty Name="Owner" Type="Oyg.Owner" />
</EntityType>
<EnumType Name="ScheduleStatus">
<Member Name="Draft" Value="0" />
<Member Name="Published" Value="1" />
<Member Name="Cancelled" Value="2" />
</EnumType>
<EntityContainer Name="OygContainer">
<EntitySet Name="Owners" EntityType="Oyg.Owner" />
<EntitySet Name="Students" EntityType="Oyg.Student" />
<EntitySet Name="Classes" EntityType="Oyg.Class">
<NavigationPropertyBinding Path="Bookings/Class" Target="Classes" />
<NavigationPropertyBinding Path="Bookings/Student" Target="Students" />
<NavigationPropertyBinding Path="Owner" Target="Owners" />
</EntitySet>
</EntityContainer>
</Schema>
<Schema Namespace="Oyg.Actions" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<Action Name="Register" IsBound="true">
<Parameter Name="bindingParameter" Type="Oyg.Class" />
<Parameter Name="studentId" Type="Edm.Guid" Nullable="false" />
<ReturnType Type="Oyg.Booking" />
</Action>
<Action Name="CancelRegistration" IsBound="true">
<Parameter Name="bindingParameter" Type="Oyg.Class" />
<Parameter Name="studentId" Type="Edm.Guid" Nullable="false" />
</Action>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Похоже, что моя ICollection of Booking не рассматривается как отдельное свойство навигации, действительно, как коллекция
{
"@odata.context": "https://localhost:44375/odata/$metadata#Classes",
"value": [
{
"Id": "dde8de4d-89ca-4ba3-cff7-08d6aac63c0f",
"Title": "xxx",
"Description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"StartTime": "2019-02-24T18:00:00+08:00",
"EndTime": "2019-02-24T19:00:00+08:00",
"Status": "Draft",
"Positions": 22,
"Bookings": []
}
]
}