wingyip
wingyip

Reputation: 3536

Convert.ChangeType throwing Invalid Cast Exception for nullable int

Getting an Invalid Cast Exception if I call the GetClaimValue method below where T is a nullable int.

private static T GetClaimValue<T>(string claimType, IEnumerable<Claim> claims)
{
    var claim = claims.SingleOrDefault(c => c.Type == claimType);

    if (claim != null)
        return (T) Convert.ChangeType(claim.Value, typeof(T));

    return default(T);
}

For example:

 GetClaimValue<int?>(IdentityServer.CustomClaimTypes.SupplierId, claims)

Anyone know of a way to deal with this?

Upvotes: 5

Views: 4097

Answers (2)

Chris Sinclair
Chris Sinclair

Reputation: 23208

I'm assuming Claim.Value is of type Object and you're dynamically converting here, you can't straight up convert an int to an int? via Convert.ChangeType.

One option is to use Nullable.GetUnderlyingType which will check if this is a nullable struct case, do the conversion via the underlying data type first, then cast to T.

You'll also need to handle the null scenario as well.

if (claim != null)
{
    var conversionType = typeof(T);

    if (Nullable.GetUnderlyingType(conversionType) != null)
    {
        if (claim.Value == null) //check the null case!
            return default(T);

        //use conversion to `int` instead if `int?`
        conversionType = Nullable.GetUnderlyingType(conversionType);
    }

    return (T)Convert.ChangeType(claim.Value, conversionType);
}

Upvotes: 8

Brandon
Brandon

Reputation: 3276

I can't explain why it's throwing an exception, however I had a similar situation when I was using Convert.ChangeType.

Try grabbing the converter of the type you pass in first, then use that to convert. I've had better results using this method.

var converter = TypeDescriptor.GetConverter(typeof(T));
return (T)converter.ConvertFrom(claim.Value);

Upvotes: 10

Related Questions