Hey again, I seem to be unable to re-open the original issue, so I had to open a new one. This #2281 is still there on nightly Microsoft.AspNet.OData 7.5.0-Nightly202009150040. Both on the sample project I linked in that issue, and in our custom project. The issue can still be reproduced in the same steps provided in that issue.
Microsoft.AspNet.OData 7.2.3 up to and including Microsoft.AspNet.OData 7.4.1 (current newest).I found this (slightly outdated) sample project, which has a complex type called "Location", similar to what we have in our project. Using that as a base, to reproduce:
http://localhost:18384/Eventshttp://localhost:18384/Events?$select=occursAtHere the "OccursAt" field is of the complex type "Location".
This is what you get on version 7.2.2 and below:
(1) {"@odata.context":"http://localhost:18384/$metadata#Events","value":[{"Id":1,"Description":null,"OccursAt":{"Address":"Address1"}}]}
(2) {"@odata.context":"http://localhost:18384/$metadata#Events(OccursAt)","value":[{"OccursAt":{"Address":"Address1"}}]}
This is what you get on versions above 7.2.2:
(1) {"@odata.context":"http://localhost:18384/$metadata#Events","value":[{"Id":1,"Description":null,"OccursAt":{"Address":"Address1"}}]}
(2) {"error":{"code":"","message":"Cannot compare elements of type 'Microsoft.OData.Service.Sample.Trippin.Models.Location'. Only primitive types, enumeration types and entity types are supported."}}
@MathiasJor How about this version?
@MathiasJor Alright,
1)
https://www.myget.org/feed/webapinetcore/package/nuget/Microsoft.AspNet.OData/7.5.0-Nightly202009142118
should work, it hardly removes the null check.
now works at my side. It comes from this PR https://github.com/OData/WebApi/pull/2285.

The previous (Nightly202009150040) nightly can't work because the Restier Trippin service is using this, the old implementation can't process this provider and any other customized provider.
Let me know any problem.
So now it seems to work fine for the sample project, thanks :). We are not using Restier in our project.
However, in our actual project we also have a custom serializer, and this still fails for all of our complex types.
A simplified example of our serializer:

Attempting to get the ResourceInstance of the expanded resource fails, but only when selecting a complex type (similar query to the original issue). Selecting any normal entity, or primitive property works as expected.
System.ArgumentException
HResult=0x80070057
Message=Objekt av typen Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll`1[Modulus.OData.Domain.Models.Klassifikation.ODataClassificationValue] kan ikke konverteres til typen Modulus.OData.Domain.Models.Klassifikation.ODataClassificationValue.
Source=mscorlib
StackTrace:
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at Microsoft.AspNet.OData.ResourceContext.BuildResourceInstance()
at Microsoft.AspNet.OData.ResourceContext.get_ResourceInstance()
at Modulus.OData.Host.Serialization.ODataMaskingSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext) in D:\Mathias\Jobb\NCCGV0010\Solution\Platform\OData\Modulus.OData.Host\Serialization\ODataMaskingSerializer.cs:line 35
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralPropertyBag(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteResource(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteComplexAndExpandedNavigationProperty(IEdmProperty edmProperty, SelectItem selectItem, ResourceContext resourceContext, ODataWriter writer)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteComplexProperties(SelectExpandNode selectExpandNode, ResourceContext resourceContext, ODataWriter writer)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteResource(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.ODataOutputFormatterHelper.WriteToStream(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, IWebApiUrlHelper internaUrlHelper, IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func`2 getODataMessageWrapper, Func`2 getEdmTypeSerializer, Func`2 getODataPayloadSerializer, Func`1 getODataSerializerContext)
at Microsoft.AspNet.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
This exception was originally thrown at this call stack:
[External Code]
Modulus.OData.Host.Serialization.ODataMaskingSerializer.CreateStructuralProperty(Microsoft.OData.Edm.IEdmStructuralProperty, Microsoft.AspNet.OData.ResourceContext) in ODataMaskingSerializer.cs
[External Code]
Below is an excerpt of our entity model with the complex type "ODataClassificationValue". Selecting type ($select=type) on our ODataActivity entity causes the provided stacktrace. In our serializer we're trying to get the "parent" entity to determine if it inherits from a specific interface (ISensitive), which it does in this example.
public partial class ODataActivity : Entity, ISensitive
{
public ODataClassificationValue Type { get; set; }
...
}
I realize this is slightly vague. I can't upload our entire project unfortunatly. Let me know if I can provide any specific details.
I found another slightly different anomaly in our serializer. Consider the entity:
public partial class ODataActivity : Entity, ISensitive
{
public ODataClassificationValue Type { get; set; }
public DateTime EventDate { get; set; }
...
}
DateTime is the standard system.DateTime.
An empty query to Activity works fine: ***/odata/Activity. This returns everything as expected:
{
"@odata.context":"http://localhost:40688/odata/$metadata#Activity",
"value":[
{
"eventDate":"2020-10-28T08:43:00+01:00",
"type":{
"userDefinedKey":"Type22",
"title":"Klage"
},
}
]
}
***/odata/Activity?$select=eventDate works fine. ***/odata/Activity?$select=type. ***/odata/Activity?$select=eventDate,type. Fails to instantiate the ResourceInstance for the original ResourceContext (so we no longer need to access the ExpandedResource before we reach an invalid ResourceInstance)
System.ArgumentException
HResult=0x80070057
Message=Objekt av typen Microsoft.AspNet.OData.Query.Expressions.SelectExpandBinder+SelectAll`1[Modulus.OData.Domain.Models.Klassifikation.ODataClassificationValue] kan ikke konverteres til typen Modulus.OData.Domain.Models.Klassifikation.ODataClassificationValue.
Source=mscorlib
StackTrace:
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
at Microsoft.AspNet.OData.ResourceContext.BuildResourceInstance()
at Microsoft.AspNet.OData.ResourceContext.get_ResourceInstance()
at Modulus.OData.Host.Serialization.ODataMaskingSerializer.CreateStructuralProperty(IEdmStructuralProperty structuralProperty, ResourceContext resourceContext) in D:\Mathias\Jobb\NCCGV0010\Solution\Platform\OData\Modulus.OData.Host\Serialization\ODataMaskingSerializer.cs:line 32
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateStructuralPropertyBag(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteResource(Object graph, ODataWriter writer, ODataSerializerContext writeContext, IEdmTypeReference expectedType)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSetSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
at Microsoft.AspNet.OData.Formatter.ODataOutputFormatterHelper.WriteToStream(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, IWebApiUrlHelper internaUrlHelper, IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func`2 getODataMessageWrapper, Func`2 getEdmTypeSerializer, Func`2 getODataPayloadSerializer, Func`1 getODataSerializerContext)
at Microsoft.AspNet.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
This exception was originally thrown at this call stack:
[External Code]
Modulus.OData.Host.Serialization.ODataMaskingSerializer.CreateStructuralProperty(Microsoft.OData.Edm.IEdmStructuralProperty, Microsoft.AspNet.OData.ResourceContext) in ODataMaskingSerializer.cs
[External Code]
Again, please just let me know if I can provide any additional information.
I was able to recreate the serializer issue in the trippin sample. I uploaded the modified version to https://github.com/MathiasJor/ODataComplexTypeIssueSample repository. Try to run these queries:
http://localhost:18384/Events (Should work as expected)
http://localhost:18384/Events?$select=occursAt Throws error at line 51 of CustomODataSerializerProvider. http://localhost:18384/Events?$select=occursAt,testTime Throws error at line 47 of CustomODataSerializerProvider.
@MathiasJor There's some feature gaps that can't create the Resource instance if a select or expand in the query.
I have a quick fix at #2288, Would you please try this nightly Microsoft.AspNet.OData.7.5.0-Nightly202009152040?
It should work and it worked at my side using your github repo.

Yes, that seems to work on my end!
Thanks a lot for your quick responses and help :). So we can assume this will be available with the release of 7.5.0? :).
Merged the PR https://github.com/OData/WebApi/pull/2288, it will be in 7.5 RTM
Hi @MathiasJor the fix for this issue introduced another (#2316). We've got another fix in flight (#2320) but I want to ensure it doesn't regress your scenario again - could you validate that Nightly202010092336 still works for you?