-
Notifications
You must be signed in to change notification settings - Fork 473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Urls targeting collections of EdmComplexObjects fail to serialize. #1597
Comments
@mtroth-microsoft I don't know why did you get such error. It should work for the current ASP.NET OData library. Did you implement the correct method in your entityset controller? In the convention routing, the method name should be : |
Yes. Are you sure yours is a typeless model? I have no Clr classes anywhere in my component.
Check the logic in the ODataResourceSetSerializer.WriteObject method. When it calls into the context to get the type it needs to get back the IEdmCollectionType with EntityType equal to the EdmTypeReference for the query. but notice the logic in the context, its if else checks if the type is IEdmObject on the one hand and in the model with a declared type on the other. it fails in the first case because it is not an IEdmObject but a list of them. it fails in the other case because there is no strongly typed class associated with the declared resource in the model. the lookup returns null and the writeobject method barfs. if I add a handler to the context's GetEdmType method to properly handle the case where the passed in type is a collection of IEdmObjects, the serializer is able to properly handle the case.
|
Yes. It should work for untyped (typeless) model. public static IEdmModel GetUntypedModel()
{
var model = new EdmModel();
var customer = new EdmEntityType("NS", "Customer");
customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
model.AddElement(customer);
var address = new EdmComplexType("NS", "Address");
address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
model.AddElement(address);
customer.AddStructuralProperty("Addresses", new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(address, true))));
var container = new EdmEntityContainer("NS", "Default");
var customers = new EdmEntitySet(container, "Customers", customer);
model.AddElement(container);
container.AddElement(customers);
return model;
} In the controller, I have: IEdmCollectionTypeReference edmType;
var model = Request.GetModel();
var address = model.SchemaElements.OfType<IEdmComplexType>().First();
edmType = new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(address, true)));
EdmComplexObjectCollection collection = new EdmComplexObjectCollection(edmType);
EdmComplexObject complex = new EdmComplexObject(address);
complex.TrySetPropertyValue("City", "RedmondUntyped");
collection.Add(complex);
complex = new EdmComplexObject(address);
complex.TrySetPropertyValue("City", "BellevueUntyped");
collection.Add(complex);
return Ok(collection); I can get: |
what serializer are you using? |
@mtroth-microsoft I did not change or add anything. I think I used the default serializer. |
probably a difference in how the models are created then. I have created a PR against this item so you can see what is needed to make the scenario work for someone who is loading their model directly off of a CSDL and returning both entity sets and sets of complex objects that have no type. |
@mtroth-microsoft I created a sample for you to reference, it's at: https://github.com/OData/ODataSamples/tree/master/WebApiCore/ODataUntypedSample2 |
I don’t need this sample. I have a repro of the problem, Sam.
I have submitted a PR that addresses the issue.
|
@mtroth-microsoft The PR #1607 looks you want to process the serialization of IEnumerable < IEdmEntityObject > or IEnumerable < IEdmComplexObject >, right? |
Yes; I think the difference is in @xuzhg's sample, even though CLR types are not used, the Edm type "Address" is defined. In @mtroth-microsoft's case there is no Edm type defined for Address -- the collection of complex type uses Collection(Edm.ComplexType). |
@mikepizzo Now, I see. Just like the property named "Addresses". <EntityType Name="Customer" >
...
<Property Name="Addresses" Type="Collection(Edm.ComplexType)" />
</EntityType> |
@xuzhg @mikepizzo As discussed, the correct fix for this issue should be to update EdmEntityCollection to handle collection of Edm.Complextype, Edm.EnitityType, Edm.Primitive, and Edm.Untyped. |
if I target the entity set:
/Entities/key
and the entity type contains a Collection(ComplexType) property, the result works as expected. But when I navigate directly to that property, the service errors out because the media formatter is unable to find a qualifying serializer to handle List.
/Entities/key/ListOfComplexObjects
this was tested against master.
The text was updated successfully, but these errors were encountered: