Cant cast ExtraProperty to the needed class
Is there an existing issue for this?
- [x] I have searched the existing issues
Description
public static List<Article>? GetFavouriteArticles( this IdentityUser user) { return user.GetProperty( ArthiveConsts.FavouriteArticlesPropertyName).As<List<Article>?>(); }
This is code in the extension file
When i call it, appears problem:
Unable to cast object of type 'System.Text.Json.JsonElement' to type 'System.Collections.Generic.List1[Arthive.Articles.Article]'. System.InvalidCastException: Unable to cast object of type 'System.Text.Json.JsonElement' to type 'System.Collections.Generic.List1[Arthive.Articles.Article]'.
Reproduction Steps
Cast nonGeneric GetProperty in the extension
Expected behavior
No response
Actual behavior
No response
Regression?
No response
Known Workarounds
No response
Version
8.2.1
User Interface
MVC
Database Provider
EF Core (Default)
Tiered or separate authentication server
None (Default)
Operation System
Windows (Default)
Other information
No response
hi
Please share some code to reproduce, Thanks.
public static List
? GetFavouriteArticles( this IdentityUser user) { return user.GetProperty( ArthiveConsts.FavouriteArticlesPropertyName).As<List?>(); }
when controller calls this method [HttpGet] [Route("{id:guid}/get-favourite-articles")] public Task<List<ArticleDto>?> GetFavouriteArticlesAsync( Guid id) { return _userProfileAppService.GetFavouriteArticlesAsync(id); }
to reproduce Cast nonGeneric GetProperty in the extensionMethod to the needed object
hi
What does your SetProperty code look like?
What type did you set for the property?
List? is an open generic type, which is not valid on its own. That’s likely why you're seeing the error. You need to specify the generic argument for List<T>, like this:
return user.GetProperty(ArthiveConsts.FavouriteArticlesPropertyName) .As<List<Article>?>();
Make sure that the type matches whatever you originally stored in the property.
I'm trying to reproduce this problem. Can you share a simple project?
Thanks.
Hello! I changed logic a little, now i using List of Guid, but have the same problem
public static List<Guid>? GetFavouriteArticles(
this IdentityUser user)
{
return user.GetProperty(
ArthiveConsts.FavouriteArticlesPropertyName).As<List<Guid>?>();
}
public static void SetFavouriteArticles(
this IdentityUser user,
List<Guid> favouriteArticles)
{
user.SetProperty(
ArthiveConsts.FavouriteArticlesPropertyName, favouriteArticles);
}
and the error
Unable to cast object of type 'System.Text.Json.JsonElement' to type 'System.Collections.Generic.List1[System.Guid]'. System.InvalidCastException: Unable to cast object of type 'System.Text.Json.JsonElement' to type 'System.Collections.Generic.List1[System.Guid]'.
at Arthive.Profiles.IdentityUserExtension.GetFavouriteArticles(IdentityUser user) in C:\Users\MisterCat100\source\repos\arthive.server\aspnet-core\src\Arthive.Domain\Profiles\IdentityUserExtension.cs:line 44
at Arthive.Profiles.UserProfileAppService.GetFavouriteArticlesAsync(Guid id) in C:\Users\MisterCat100\source\repos\arthive.server\aspnet-core\src\Arthive.Application\Profiles\UserProfileAppService.cs:line 80
What type did you set for the property?
List? is an open generic type, which is not valid on its own. That’s likely why you're seeing the error. You need to specify the generic argument for List, like this:
return user.GetProperty(ArthiveConsts.FavouriteArticlesPropertyName) .As<List<Article>?>();Make sure that the type matches whatever you originally stored in the property.
Github eaten part of the code, i used .As<List<Article>?>();
i resolved the problem, by serializing JsonElement, but cat you please explain, why returns JsonElement, when writes, that will return object?
Here, how it wrote in the debugger variables
hi
Can you share a test project to reproduce it?
Thanks.
hi
Can you share a test project to reproduce it?
Thanks.
you dont need test project, so why returns JsonElement, when writes, that will return object?
The ExtraPropertyDictionary lacks Type information. It doesn't know what Type to deserialize.
You can add a custom JsonConverter.
class BarDtoJsonConverter : JsonConverter<BarDto>
{
private JsonSerializerOptions _readJsonSerializerOptions;
private JsonSerializerOptions _writeJsonSerializerOptions;
public override BarDto Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
_readJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(BarDtoJsonConverter));
var barDto = JsonSerializer.Deserialize<BarDto>(ref reader, _readJsonSerializerOptions);
var extraProperties = barDto.ExtraProperties;
if (extraProperties.TryGetValue("bar", out var barValue) && barValue is JsonElement jsonElement)
{
if (jsonElement.ValueKind == JsonValueKind.Array)
{
var barList = new List<string>();
foreach (var item in jsonElement.EnumerateArray())
{
if (item.ValueKind == JsonValueKind.String)
{
barList.Add(item.GetString());
}
}
barDto.SetProperty("bar", barList);
}
}
return barDto;
}
public override void Write(Utf8JsonWriter writer, BarDto value, JsonSerializerOptions options)
{
_writeJsonSerializerOptions ??= JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(BarDtoJsonConverter));
JsonSerializer.Serialize(writer, value, _writeJsonSerializerOptions);
}
}
Thank you very much for explanation! So, if it lacks of type, why writes, that it is JsonElement?
We used the Microsoft recommended way.
https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/converters-how-to#deserialize-inferred-types-to-object-properties