Skip to content
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

Open
mtroth-microsoft opened this issue Aug 30, 2018 · 12 comments
Open

Comments

@mtroth-microsoft
Copy link
Contributor

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.

@KanishManuja-MS KanishManuja-MS self-assigned this Aug 30, 2018
@xuzhg
Copy link
Member

xuzhg commented Aug 31, 2018

@mtroth-microsoft I don't know why did you get such error. It should work for the current ASP.NET OData library.

image

Did you implement the correct method in your entityset controller? In the convention routing, the method name should be : Get{ComplexPropertyName}

@mtroth-microsoft
Copy link
Contributor Author

mtroth-microsoft commented Aug 31, 2018 via email

@xuzhg
Copy link
Member

xuzhg commented Aug 31, 2018

Yes. It should work for untyped (typeless) model.
For example, I have the following untyped model. (Without CLR type).

        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:

image

@mtroth-microsoft
Copy link
Contributor Author

what serializer are you using?

@xuzhg
Copy link
Member

xuzhg commented Sep 4, 2018

@mtroth-microsoft I did not change or add anything. I think I used the default serializer.

@mtroth-microsoft
Copy link
Contributor Author

mtroth-microsoft commented Sep 4, 2018

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.

@xuzhg
Copy link
Member

xuzhg commented Sep 4, 2018

@mtroth-microsoft I created a sample for you to reference, it's at: https://github.com/OData/ODataSamples/tree/master/WebApiCore/ODataUntypedSample2

@mtroth-microsoft
Copy link
Contributor Author

mtroth-microsoft commented Sep 4, 2018 via email

@xuzhg
Copy link
Member

xuzhg commented Sep 4, 2018

@mtroth-microsoft The PR #1607 looks you want to process the serialization of IEnumerable < IEdmEntityObject > or IEnumerable < IEdmComplexObject >, right?

@mikepizzo
Copy link
Member

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).

@xuzhg
Copy link
Member

xuzhg commented Sep 4, 2018

@mikepizzo Now, I see. Just like the property named "Addresses".

<EntityType Name="Customer" >
     ...
    <Property Name="Addresses" Type="Collection(Edm.ComplexType)" />
</EntityType>

@KanishManuja-MS
Copy link
Contributor

KanishManuja-MS commented Apr 3, 2019

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants