Маршрутизация атрибутов OData для удаления связи между сущностями m:m
Сценарий представляет собой приложение, которое использует OData v4, серверный API на основе модели Entity Framework, использующей ODataLib, на стороне клиента, использующей расширение генератора клиентского кода OData для Visual Studio.
Мне не удается заставить работать маршрутизацию атрибутов OData для удаления отношений для сущностей в отношениях m:m, для которых клиент генерирует запросы DELETE в форме:
http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1)
Маршрутизация атрибутов для POST для создания ссылки работает просто отлично - идентификатор связанной сущности кодируется в теле, и работает следующее объявление метода действия контроллера (сам контроллер имеет [ODataRoutePrefix("tblTestRestaurant")]
):
[ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
[HttpPost]
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public async Task<IHttpActionResult> PostAttachtblTestDishes([FromODataUri] int pRestaurantID,
[FromBody] Uri uri) { ... }
Но я не могу получить что-то подобное, работающее для DELETE, где идентификатор связанной сущности указан с помощью $ref?id=...
синтаксис в URL.
Я пробовал следующее с помощью атрибута ODataRoute:
[ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef1([FromODataUri] int pRestaurantID,
[FromODataUri] Uri relatedUri)
{
throw new NotImplementedException();
}
[ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef2([FromODataUri] int pRestaurantID,
[FromODataUri] string relatedUri)
{
throw new NotImplementedException();
}
[ODataRoute("({pRestaurantID})/tblTestDishes/$ref?$id={pRelated}")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef3([FromODataUri] int pRestaurantID,
[FromODataUri] string pRelated)
{
throw new NotImplementedException();
}
[ODataRoute("({pRestaurantID})/tblTestDishes/$ref?$id={pRelated}")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef4([FromODataUri] int pRestaurantID,
[FromODataUri] Uri pRelated)
{
throw new NotImplementedException();
}
Но ни одно из приведенных выше действий контроллера не будет выполнено в ответ на запрос DELETE для http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1)
,
Единственный способ заставить его работать - это не использовать атрибутную маршрутизацию, а вместо этого полагаться на соглашения о маршрутизации OData, т.е.
[HttpDelete]
public async Task<IHttpActionResult> DeleteRef([FromODataUri] int key,
[FromODataUri] string relatedKey, string navigationProperty)
{
throw new NotImplementedException();
}
Этот метод основан на тестировании строки navigationProperty, чтобы определить, какое свойство навигации коллекции на объекте нужно изменить, - вместо этого я предпочел бы использовать маршрутизацию атрибутов и иметь отдельный метод действия в моем контроллере для каждого свойства навигации коллекции.
Я использовал ряд учебных пособий и документации, в частности https://damienbod.wordpress.com/2014/06/10/getting-started-with-web-api-and-odata-v4/
Я также прошел через несколько тестовых примеров OData WebApi, в частности, этот, который использует комбинацию маршрутизации атрибутов и соглашений о маршрутизации OData - но не содержит пример маршрутизации атрибутов для удаления ссылок.
Поэтому мой вопрос - какой синтаксис атрибута ODataRoute и параметры метода я должен использовать, предполагая, что атрибут ODataRoute поддерживает этот...$ref? Id=... синтаксис в URL для удалений; а если нет, то какие есть альтернативы?
1 ответ
Web API OData разбирает Uri в $Id
создать ключевой сегмент, добавленный к исходным сегментам пути. Итак, если вы измените шаблон, как показано ниже, он должен работать:
[ODataRoute("({pRestaurantID})/tblTestDishes({pRelated})/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef([FromODataUri] int pRestaurantID, [FromODataUri] int pRelated)
{
...
}
Вы можете обратиться к моему примеру проекта здесь. Надеюсь, это поможет вам. Благодарю.