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

Enums that don't inherit from int throw errors when attempting to bind #48

Open
AzaleaHarper opened this issue Dec 14, 2021 · 1 comment

Comments

@AzaleaHarper
Copy link

AzaleaHarper commented Dec 14, 2021

In our project we use enums that are inheriting from byte, but the FlagsEnumModelBinder and FlagsEnumModelBinderProvider only handle the case where the enum is of type int.

I've managed to get it to work as intended by checking the underlying enum type and then returning a model binder that matches that type.

FlagsEnumModelBinderProvider

public IModelBinder GetBinder([NotNull] ModelBinderProviderContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            if (IsNotFlagsEnum(context))
            {
                return null;
            }

            var enumType
                = Enum.GetUnderlyingType(context.Metadata.UnderlyingOrModelType);

            if (enumType == typeof(int))
            {
                return new FlagsEnumIntModelBinder();
            }
            if (enumType == typeof(byte))
            {
                return new FlagsEnumByteModelBinder();
            }
            if (enumType == typeof(short))
            {
                return new FlagsEnumShortModelBinder();
            }
            if (enumType == typeof(long))
            {
                return new FlagsEnumLongModelBinder();
            }

            throw new InvalidOperationException(
                $"enums inheriting of type '{enumType.FullName}' are not supporeted.");
        }

And then in each ModelBinder on the aggregate I change the cast to the expected type.
byte
var result = actualValues.Aggregate(0, (current, value) => (byte)(current | (byte)value));
short
var result = actualValues.Aggregate(0, (current, value) => (short)((short)current | (short)value));
long
var result = actualValues.Aggregate((long)0, (current, value) => (current | (long)value));

@AdamWillden
Copy link

AdamWillden commented Dec 23, 2021

@sgjsakura we found the simpler fix which is to change this line

from:
var result = actualValues.Aggregate(0, (current, value) => current | (int)value);
to:
var result = actualValues.Aggregate(0UL, (current, value) => current | Convert.ToUInt64(value));

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

2 participants