Ответ 1
В одном из наших проектов мы также используем общий базовый класс ODataController, где мы фактически используем GetEntity
для извлечения отдельных объектов и GetEntitySet
для извлечения списка объектов.
В соответствии с указанным вами URL-адресом и результирующим сообщением об ошибке структура ODATA не может найти ODataAction для ~/entityset
. Как вы указали http://localhost:10000/odata/MyObjects
в качестве примера, рассматриваемое действие не может быть public SingleResult<T> GetEntity([FromODataUri] int key)
, так как это соответствует только запросу http://localhost:10000/odata/MyObjects(42)
.
Наш код для общего контроллера выглядит следующим образом:
public abstract class OdataControllerBase<T> : ODataController
where T : class, IIdentifiable, new()
{
protected OdataControllerBase(/* ... */)
: base()
{
// ...
}
public virtual IHttpActionResult GetEntity([FromODataUri] long key, ODataQueryOptions<T> queryOptions)
{
// ...
return Ok(default(T));
}
public virtual async Task<IHttpActionResult> GetEntitySet(ODataQueryOptions<T> queryOptions)
{
// ...
return Ok<IEnumerable<T>>(default(List<T>));
}
public virtual IHttpActionResult Put([FromODataUri] long key, T modifiedEntity)
{
// ...
return Updated(default(T));
}
public virtual IHttpActionResult Post(T entityToBeCreated)
{
// ...
return Created(default(T));
}
[AcceptVerbs(HTTP_METHOD_PATCH, HTTP_METHOD_MERGE)]
public virtual IHttpActionResult Patch([FromODataUri] long key, Delta<T> delta)
{
// ...
return Updated(default(T));
}
public virtual IHttpActionResult Delete([FromODataUri] long key)
{
// ...
return Updated(default(T));
}
}
Тогда код для конкретного контроллера меньше:
public partial class KeyNameValuesController : OdataControllerBase<T>
{
public KeyNameValuesController(/* ... */)
: base()
{
// there is nothing to be done here
}
}
Однако мы выяснили, что оба метода Get (для одиночного результата и перечислимого результата) действительно должны начинаться с Get
. Сначала мы попробовали List
вместо GetEntitySet
, и это не сработало, так как фреймворк затем ожидает POST
для действия List
).
Фактически вы можете проверить и диагностировать процесс разрешения, предоставив пользовательский IHttpActionSelector
, как описано в Маршрутизация и действие в ASP.NET Web API (смотря на ASP.NET WEB API 2: жизненный цикл HTTP-сообщений также может быть стоит).
Таким образом, можно использовать GetEntity
как имя метода, которое вы первоначально пытались использовать в своем примере, и нет необходимости переименовывать его в простой Get
. Кроме того, нет необходимости в каких-либо изменениях в вашей конфигурации ODATA.