使用Date的动态属性进行OData过滤

时间:2016-12-15 14:04:42

标签: c# odata asp.net-4.5

我创建了一个名为Document的EntityType,它包含动态属性:

public class Document
{
    public int Id { get; set; }
    public DateTime CreatedAt { get; set; }
    public IDictionary<string, object> DynamicProperties { get; set; }
}

My DocumentsController返回单个Document的列表,该列表具有三种不同类型的DateTime,int和string的动态属性。

[EnableQuery]
public IHttpActionResult Get()
{
    return Ok(_documents.AsQueryable());
}

private List<Document> _documents = new List<Document>
{
    new Document
    {
        Id = 1,
        CreatedAt = DateTime.Now,
        DynamicProperties = new Dictionary<string, object>
        {
            { "DynamicDate", DateTime.Now.AddMonths(1) },
            { "DynamicInt", 10 },
            { "DynamicString", "abc" },
        }
    }
};

当我使用/odata/Documents?$filter=CreatedAt gt 2016-01-01T00:00:00Z查询API时,过滤器按预期工作。使用$filter=DynamicInt gt 9$filter=DynamicString gt 'aaa'过滤其他动态属性也会产生我想象的方式。

但是当我尝试使用$filter=DynamicDate gt 2016-01-01T00:00:00Z时,会抛出以下异常:

{
  "error": {
    "code": "",
    "message": "An error has occurred.",
    "innererror": {
      "message": "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=full'.",
      "type": "System.InvalidOperationException",
      "stacktrace": "",
      "internalexception": {
        "message": "Specified cast is not valid.",
        "type": "System.InvalidCastException",
        "stacktrace": "   at lambda_method(Closure , Document )\r\n   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()\r\n   at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)\r\n   at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n   at System.Web.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\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.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
      }
    }
  }
}

只需从API中检索具有完整元数据的文档,即可获得:

{
  "@odata.context": "http://localhost:58245/odata/$metadata#Documents",
  "value": [
    {
      "@odata.type": "#DocumentArchive.API.Models.Document",
      "@odata.id": "http://localhost:58245/odata/Documents(1)",
      "@odata.editLink": "http://localhost:58245/odata/Documents(1)",
      "Id": 1,
      "CreatedAt@odata.type": "#DateTimeOffset",
      "CreatedAt": "2016-12-15T14:53:01.9903785+01:00",
      "DynamicDate@odata.type": "#DateTimeOffset",
      "DynamicDate": "2017-01-15T14:53:01.9903785+01:00",
      "DynamicInt": 10,
      "DynamicString": "abc"
    }
  ]
}

如何过滤作为日期的动态属性?

我正在使用:Microsoft.AspNet.OData 5.9.1

0 个答案:

没有答案