在 ODataController 端点上指定 $select 时出现序列化错误

Serialization error when specifying $select on ODataController endpoint

我一直在使用 Web API 2 和 OWIN 开发 RESTful 网络服务。最初我的控制器继承自 ApiController,并且 GET 操作支持 OData filtering/queries 即标有 [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)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Owin.HttpMessageHandlerAdapter.<BufferResponseContentAsync>d__13.MoveNext()"
    }
  }
}

我很困惑这是如何与 ApiController 一起工作的,但不是与 ODataController 一起工作的!有什么我想念的吗?

干杯!

好的,我知道发生了什么:

我尝试将我的 OData 包更新到最新版本以获得 OData v4 支持。 Microsoft .Net OData 库命名空间在 OData v3 (System.Web.Http.OData) 和 v4 (System.Web.OData) 之间发生了变化。我以某种方式混合了这些库,以至于我引用了旧 OData 库中的 EnableQuery 属性,这导致了序列化问题。

追踪起来不是一个明显的问题 - 当属性具有相同的名称但在不同的命名空间中并且实际上属于完全不同的版本时发生了什么并不明显!