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

Odata returns generic type error when enum is a key #2964

Closed
biboller opened this issue May 15, 2024 · 14 comments · Fixed by #3013
Closed

Odata returns generic type error when enum is a key #2964

biboller opened this issue May 15, 2024 · 14 comments · Fixed by #3013
Assignees
Labels

Comments

@biboller
Copy link

Our project uses enums as keys. For example we use weekday as a key here.

image

This wouldn’t be a problem expect that when getting the data from odata the mapping fails with the following error:

       This operation is only valid on generic types.

Assemblies affected

Microsoft.OData.Core 7.x

Reproduce steps

Add an enum as a key

Expected result

We expect enum's to be useable as keys

Additional detail

In the file OdatatypeInfo.cs in the method GetKeyProperties() we found that the program assumes that the property should be generic type and afterwards checks if it is an enum.

image

We think the order should be changed in the if statement and the IsEnum() should be inverted.

Are we over looking something? We tried getting, updating and posting data with this change. Which all worked without problem

image
@gathogojr gathogojr self-assigned this May 21, 2024
@mikepizzo
Copy link
Member

mikepizzo commented May 21, 2024

Yes, we should support enums as keys.

@gathogojr -- Note: that the code shown above as the current logic in the first block is slightly different than what I see in the repo.

In the repo, the conditional check is:

                if (!PrimitiveType.IsKnownType(key.PropertyType) && !(key.PropertyType.GetGenericTypeDefinition() == typeof(System.Nullable<>) && key.PropertyType.GetGenericArguments().First().IsEnum()))

which is different than above reported code in that:

  1. the IsEnum check is on keyProperty.PropertyTypeGetGenericArguments().First().IsEnum(), rather than keyProperty.PropertyType.IsEnum()
  2. the IsEnum check is grouped with the GetGenericTypeDefinition() check rather than a separate check

I suspect the reason that the fixed code doesn't throw is not because of ordering, or even grouping, but because it doesn't call GetGenericArguments.

I'm not sure the rationale behind the existing logic that would make us think that an unknown type must be generic (or why we specifically check for an enum if it is), but if we don't know for sure that key.PropertyType is generic we should check IsGenericType before calling GetGenericTypeDefinition or GetGenericArguments.

@kyleweishaupt
Copy link

I'm also encountering the same issue when attempting to access the Microsoft Business Central API through OData V4. We're using the latest Microsoft.OData NuGet packages, 7.21.1. Any attempt to enumerate a collection with an enum key returns the error about generic types, even when trying to project to a new class.

@nmushovic
Copy link

To expand on the above, it looks like the Business Central API converted quite a few string to Enums. The ItemReference class uses an Enum as a key field and we're getting the error in GetKeyProperties().

image

@biboller
Copy link
Author

@mikepizzo Yes the problem seems to be that GetGenericTypeDefinition is called too early. The code should accept simple types and enums as valid keys and reject generic types. So changing the ordering of the if statement ensures that GetGenericTypeDefinition isn't called if the key is an enum. Can we contribute on this issue by creating a pr to fix this?

@MikkelGlerup
Copy link

Any news on this?
We're having the same problem when using Odata together with Business Central

@nmushovic
Copy link

We used a work around by selecting odatakeys and not selecting the enum key fields. https://www.cloudfronts.com/blog/d365-business-central/using-odatakeyfields-for-fetching-records-in-business-central-web-services/

@MikkelGlerup
Copy link

Sadly that isn't going to work for me.
I'm getting the error when running this code
var linesQuery = new DataServiceCollection<MtSalesInvoiceLine>(_mtApiContext.MtSalesInvoiceLines.AddQueryOption("$expand", "dimensionSetLines").Where(s => s.DocumentId == salesOrder.Id));

There's an enum key field somewhere in the hierarchy.

Will update when I find a solution though

@MikkelGlerup
Copy link

Found out my error was due to breaking changes being introduced on Business Centrals side with version "24.1.18927.19282". Running the same code towards an Business Central Cloud environment running "24.0.16410.17628" succeeds.

@nmushovic
Copy link

@MikkelGlerup , do you have a link to the breaking change?

@MikkelGlerup
Copy link

MikkelGlerup commented Jun 13, 2024

@nmushovic I made my own issue and gave it more details here

EDIT:
I was wrong, it had nothing to do with version

@martinfbluesoftcz
Copy link

Hello, can someone to aprove this fix: #3013
It is critical because our app which communicates with MS Bussiness Central does not work after new API definition with enums was updated.
@gathogojr @habbes @xuzhg @ElizabethOkerio @paulodero
Thank you very much.

@mikepizzo
Copy link
Member

mikepizzo commented Jul 11, 2024 via email

@martinfbluesoftcz
Copy link

@mikepizzo It looks fine now.

@martinBluesoft
Copy link

Do you know when a new version with a fix for this bug will be released?

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

Successfully merging a pull request may close this issue.

8 participants