从未绑定函数返回集合会产生序列化错误

时间:2015-03-19 20:56:24

标签: asp.net-web-api odata odata-v4

我有以下设置,应该返回一个FooBars列表。但由于某种原因,它无法序列化:(

配置

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.Function("Test").ReturnsCollection<FooBar>();
config.MapODataServiceRoute(routeName: "OData",
    routePrefix: "OData",
    model: builder.GetEdmModel());

未约束功能

[HttpGet]
[ODataRoute("Test")]
public IEnumerable<FooBar> Test()
{
    var foobars = new List<FooBar>();
    // populate list...
    return foobars;
}

错误

调用 localhost / odata / Test 会出现以下错误

{
    "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": "The related entity set could not be found from the OData path. The related entity set is required to serialize the payload.",
                "type": "System.Runtime.Serialization.SerializationException",
                "stacktrace": "   at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.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()"
            }
        }
    }
}

$ Metadata代码段

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" 
    xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="MyNamespace" 
            xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="FooBar">
                <Key>
                    <PropertyRef Name="Id" />
                </Key>
                <Property Name="Id" Type="Edm.Int32" Nullable="false" />
                <Property Name="A" Type="Edm.String" />
                <Property Name="B" Type="Edm.Int32" Nullable="false" />
                <Property Name="C" Type="Edm.Int32" Nullable="false" />
            </EntityType>
            <EntityType Name="FooBarD" BaseType="MyNamespace.FooBar">
                <Property Name="D" Type="Edm.Int32" Nullable="false" />
            </EntityType>
            <EntityType Name="FooBarE" BaseType="MyNamespace.FooBar">
                <Property Name="E" Type="Edm.Int32" Nullable="false" />
            </EntityType>
        </Schema>
        <Schema Namespace="Default" 
            xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <Function Name="Test">
                <ReturnType Type="Collection(MyNamespace.FooBar)" />
            </Function>
            <EntityContainer Name="Container">
                <FunctionImport Name="Test" Function="Default.Test" IncludeInServiceDocument="true" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

1 个答案:

答案 0 :(得分:3)

原来,因为我设置了此builder.EntitySet<FooBar>("BAM");,我需要调用ReturnsCollectionFromEntitySet

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<FooBar>("BAM"); // previously omitted from example
builder.Function("Test").ReturnsCollectionFromEntitySet<FooBar>("BAM")();
config.MapODataServiceRoute(routeName: "OData",
    routePrefix: "OData",
    model: builder.GetEdmModel());