Ошибка сериализации при указании $select на конечной точке ODataController

Я разрабатываю веб-сервис RESTful с помощью Web API 2 и OWIN. Первоначально мои контроллеры унаследованы от ApiController, а действия GET поддерживают фильтрацию OData/запросы, т. е. помечены [EnableQuery].

Теперь мы решили посмотреть, возможно ли предоставить истинную службу OData, и поэтому сделать так, чтобы наши контроллеры унаследовали от ODataController вместо ApiController. Хотя это, кажется, работает хорошо по большей части, $select больше не работает.

public class BaseController : ODataController
{
    ... some properties here, not related to issue...
}


public class EmployeesController : BaseController
{
   private readonly AppDbContext _context = new AppDbContext();

   [EnableQuery]
   public IQueryable<Employee> Get()
   {
       return _context.Employees;
   }
   ...
}

Ошибка, которую я вижу:

{
  "error": {
    "code": "",
    "message": "An error has occurred.",
    "innererror": {
      "message": "'DbQuery`1' cannot be serialized using the ODataMediaTypeFormatter.",
      "type": "System.Runtime.Serialization.SerializationException",
      "stacktrace": "   at System.Web.OData.Formatter.ODataMediaTypeFormatter.GetSerializer(Type type, Object value, ODataSerializerProvider serializerProvider)rn   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)rn   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__13.MoveNext()"
    }
  }
}

Я озадачен, как это работает с ApiController, но не с ODataController! Я что-то упускаю?

Ура!

1 ответ

  1. Хорошо, я понял, что произошло:

    Я попытался обновить свои пакеты OData до последней версии для поддержки OData v4. Пространства имен библиотеки Microsoft .Net OData изменились между OData v3 (System.Сеть.Http.OData) и v4 (System.Сеть.OData). Мне каким-то образом удалось смешать эти библиотеки таким образом, что я ссылался на атрибут EnableQuery в старой библиотеке OData, что вызвало проблему сериализации.

    Не очевидная проблема для отслеживания — не очевидно, что происходит, когда атрибуты имеют одно и то же имя, но находятся в разных пространствах имен и на самом деле принадлежат к совершенно разным версиям!