AspNetCoreOData
AspNetCoreOData copied to clipboard
ASP.NET Core OData Action with complex type having stream always returns null for the stream
Having asp.netcore odata service that returns an action with the following complex type that has stream property.
public class customerResponse
{
public string Id { get; set; }
public Stream Photo{ get; set; }
public string Name { get; set; }
}
Here is the EDM model that is constructed:
var action = builder.EntityType<company>().Action("exportCustomers");
action.CollectionParameter<string>("customerIds");
action.ReturnsCollection<customerResponse>().;
Now there is a odata controller class that implements the following
[HttpPost]
public List<customerResponse> exportCustomers([FromRoute] string key, ODataActionParameters parameters)
{
IEnumerable<string> custIds = parameters["customerIds"] as IEnumerable<string>;
byte[] byteArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<customerResponse> responses = new List<customerResponse>();
foreach (string id in custIds)
{
customerResponse itemResponse =
new customerResponse() { Id = id, Photo = new MemoryStream(byteArray,
0, 4), Name = "ABCD" };
responses.Add(itemResponse);
}
return responses;
}
In the above example after making the call, I always see the property Photo is not present. Only the Id and Name are present in the deserialized response.
Am I missing anything with respect to handling stream with Odata ?
Thanks
@venknar can you share with use your HttpPost request URI, the request body and the corresponding response body?
It's better if you can share with us the metadata. You can get the metadata by sending "$metadata".
@venknar by the way, if you want to return the byte[] for your photo, you can use 'Edm.Binary' type, in the C# class, you can directly use byte[] to define the photo property.
Here is the 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="myCustomers" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="customer">
<Key>
<PropertyRef Name="id" />
</Key>
<Property Name="id" Type="Edm.String" Nullable="false" />
</EntityType>
<ComplexType Name="exportCustomerResponse">
<Property Name="itemId" Type="Edm.String" />
<Property Name="data" Type="Edm.Stream" />
<Property Name="changeKey" Type="Edm.String" />
<Property Name="path" Type="Edm.String" />
<Property Name="error" Type="myCustomers.error" />
</ComplexType>
<ComplexType Name="error">
<Property Name="message" Type="Edm.String" />
<Property Name="code" Type="Edm.String" />
</ComplexType>
<Action Name="exportCustomers" IsBound="true">
<Parameter Name="bindingParameter" Type="myCustomers.customer" />
<Parameter Name="ItemIds" Type="Collection(Edm.String)" />
<ReturnType Type="Collection(myCustomers.exportCustomerResponse)" />
</Action>
<EntityContainer Name="EntityContainer">
<EntitySet Name="customers" EntityType="myCustomers.customer" />
</EntityContainer>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
@venknar by the way, if you want to return the byte[] for your photo, you can use 'Edm.Binary' type, in the C# class, you can directly use byte[] to define the
photoproperty.
Are you suggesting that using Edm.Stream and Edm.Byte[] are equivalent ? The reason for using Edm.Stream was that we want to delay the writing until the data for the photo is accessed.