RESTier OData支持$ expand和$ filter的函数

时间:2015-08-07 03:38:57

标签: odata restier

在RESTier团队的帮助下,我设法创建一个RESTier函数,返回我的实体列表。

这是代码

protected EdmModel OnModelExtending(EdmModel model)
{
    var ns = model.DeclaredNamespaces.First(); // PointLoc.Data
    var entityContainer = (EdmEntityContainer) model.EntityContainer;

    var locationEntityType = (IEdmEntityType) model.FindDeclaredType(ns + "." + "Location");
    var locationEntitySet = entityContainer.FindEntitySet("Locations");
    var locationEntityTypeReference = new EdmEntityTypeReference(locationEntityType, false);
    var locationEntityCollection = EdmCoreModel.GetCollection(locationEntityTypeReference);

    var ambilLocationsByMarketId = new EdmFunction(ns, "AmbilLocationsByMarketId", locationEntityCollection, false, null, true);
    model.AddElement(ambilLocationsByMarketId);
    entityContainer.AddFunctionImport("AmbilLocationsByMarketId", ambilLocationsByMarketId,
        new EdmEntitySetReferenceExpression(locationEntitySet));

    return model;
}  

这是我在Controller上的实现

[HttpGet]
[EnableQuery]
[ODataRoute("AmbilLocationsByMarketId")]
public IQueryable<Location> AmbilLocationsByMarketId()
{
    var locations = DbContext.Locations.Where(l => l.Name.Contains("Hotel")).Select(l => l);
    return locations;
}   

使用i发送HTTP GET可以正常返回数据列表 http://localhost:21922/odata/AmbilLocationsByMarketId

但是当我尝试添加$ expand或$ filter时,它无效。 http://localhost:21922/odata/AmbilLocationsByMarketId?$扩大=分类

我的错误类似于

{
  "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=minimal'.",
      "type": "System.InvalidOperationException",
      "stacktrace": "",
      "internalexception": {
        "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, IEdmModel model, 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.Runtime.CompilerServices.TaskAwaiter.GetResult()\\\r\\\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
      }
    }
  }
}

这是我的元数据

<EntityType Name="Location">
    <Key>
        <PropertyRef Name="Id" />
    </Key>
    <Property Name="Id" Type="Edm.Int32" Nullable="false">
        <Annotation Term="Org.OData.Core.V1.Computed" Bool="true" />
    </Property>
    <Property Name="Name" Type="Edm.String" Nullable="false" MaxLength="500" />
    <Property Name="Address" Type="Edm.String" Nullable="false" MaxLength="2000" />
    <Property Name="City" Type="Edm.String" MaxLength="500" />
    <Property Name="Postcode" Type="Edm.String" MaxLength="100" />
    <Property Name="Phone" Type="Edm.String" MaxLength="50" />
    <Property Name="Email" Type="Edm.String" MaxLength="200" />
    <Property Name="Latitude" Type="Edm.Decimal" Nullable="false" Precision="9" Scale="6" />
    <Property Name="Longitude" Type="Edm.Decimal" Nullable="false" Precision="9" Scale="6" />
    <Property Name="Street" Type="Edm.String" MaxLength="1000" />
    <Property Name="UpVotes" Type="Edm.Int32" Nullable="false" />
    <Property Name="DownVotes" Type="Edm.Int32" Nullable="false" />
    <Property Name="CategoryId" Type="Edm.Int32" Nullable="false" />
    <Property Name="StatusId" Type="Edm.Int32" Nullable="false" />
    <Property Name="StateId" Type="Edm.Int32" Nullable="false" />
    <Property Name="TitleSlug" Type="Edm.String" MaxLength="200" />
    <NavigationProperty Name="Category" Type="PointLoc.Data.Category" Nullable="false" Partner="Locations">
        <ReferentialConstraint Property="CategoryId" ReferencedProperty="Id" />
    </NavigationProperty>
</EntityType>

这里是EntityContainer

<EntityContainer Name="DatabaseContext">
    <EntitySet Name="Categories" EntityType="PointLoc.Data.Category">
        <NavigationPropertyBinding Path="Locations" Target="Locations" />
    </EntitySet>
    <EntitySet Name="Locations" EntityType="PointLoc.Data.Location">
        <NavigationPropertyBinding Path="Accesses" Target="Accesses" />
        <NavigationPropertyBinding Path="Category" Target="Categories" />
        <NavigationPropertyBinding Path="Contents" Target="Contents" />
        <NavigationPropertyBinding Path="State" Target="States" />
        <NavigationPropertyBinding Path="Status" Target="Status" />
        <NavigationPropertyBinding Path="LocationMarketMaps" Target="LocationMarketMaps" />
        <NavigationPropertyBinding Path="LocationTagMaps" Target="LocationTagMaps" />
    </EntitySet>
    <FunctionImport Name="AmbilLocationsByMarketId" Function="PointLoc.Data.AmbilLocationsByMarketId" EntitySet="Locations" />
</EntityContainer>

0 个答案:

没有答案