-
Notifications
You must be signed in to change notification settings - Fork 3.6k
ExtraProperties in nested DTOs are not deserialized in Blazor WebAssembly #9581
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
Comments
HI You can try to custom the converter to handle the |
I have implemented my own The thing is - I have introduced even more nesting, 3 layers, 4 layers, etc... and all objects are deserialized perfectly fine. Just the I believe there has to be a problem with the |
Can you share your |
It is nothing really special. Just raw JSON writing and reading based on read token type. It is ignoring the public class BarDtoConverter : JsonConverter<BarDto>
{
public override BarDto Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dto = new BarDto();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
DoProperty(ref reader, dto);
break;
case JsonTokenType.EndObject:
return dto;
}
}
return dto;
}
private void DoProperty(ref Utf8JsonReader reader, BarDto dto)
{
var name = reader.GetString();
switch (name)
{
case nameof(BarDto.Value):
reader.Read();
dto.Value = reader.GetString();
break;
case nameof(BarDto.ExtraProperties):
reader.Read();
while (reader.TokenType != JsonTokenType.EndObject)
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var extraName = reader.GetString();
reader.Read();
var value = reader.GetString();
dto.SetProperty(extraName, value, false);
}
reader.Read();
}
break;
}
}
public override void Write(Utf8JsonWriter writer, BarDto value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteString(nameof(BarDto.Value), value.Value);
writer.WritePropertyName(nameof(BarDto.ExtraProperties));
writer.WriteStartObject();
foreach (var prop in value.ExtraProperties)
{
writer.WriteString(prop.Key, prop.Value.ToString());
}
writer.WriteEndObject();
writer.WriteEndObject();
}
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert == typeof(BarDto);
}
} |
See #9626 |
I have tried to replace the original In addition, I am quite unsure if the |
Can you share your steps and code?
You are right, I will update. |
I have copied both And replaced the converters like this: context.Services.Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
var converter = options.JsonSerializerOptions.Converters.FirstOrDefault(x => x is AbpHasExtraPropertiesJsonConverterFactory);
if (converter != null)
{
options.JsonSerializerOptions.Converters.Remove(converter);
}
options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory2());
}); |
Ok, I understand the issue now. Creating the new options like this: var newOptions = JsonSerializerOptionsHelper.Create(options, x =>
x == this ||
x.GetType() == typeof(AbpHasExtraPropertiesJsonConverterFactory)); will cause the converter to be removed from the available list of converters and later on, when actual deserialization is called var extensibleObject = JsonSerializer.Deserialize<T>(rootElement.GetRawText(), newOptions); it will deserialize the object itself but there will be no |
hi You can try to change the context.Services.Configure<JsonOptions>(options =>
{
var converter = options.JsonSerializerOptions.Converters.FirstOrDefault(x => x is AbpHasExtraPropertiesJsonConverterFactory);
if (converter != null)
{
options.JsonSerializerOptions.Converters.Remove(converter);
}
options.JsonSerializerOptions.Converters.Add(new AbpHasExtraPropertiesJsonConverterFactory2());
}); |
Yes, this is the point. 👍 I will try to do some refactor. |
Yes, provided commit has fixed the issue. But... I have just found that Wouldn't it be easier just to create a new |
This is the limit of |
Add proper title to Abp-permission-manager.component #9581
Hello, consider following objects/DTOs:
and service:
Both
FooDto
andBarDto
areExtensibleObject
andFooDto
has a list ofBarDto
s. If I callGetFooAsync
in my Blazor page, I will getFooDto
with its Name, Bars and ExtraProperties butBarDto
s in Bars have only Value but the ExtraProperties are empty. I have verified tha the data are sent from the AppService and have been transfered to the client (received JSON had the ExtraProperties filled).However calling the
GetBarAsync
orGetBarsAsync
will result in getting theBarDto
(s) with ExtraProperties containing all relevant data.All these observations makes me believe there is an issue with the deserialization of received JSON on the Blazor side. Maybe this is some kind of limitation or misconfiguration of the JsonSerializer.
Any ideas or advices will be much appriciated. I don't really like the idea/workaround to create new method just to receive the dto with ExtraProperties filled which could result in N+1 data retrieval problem.
The text was updated successfully, but these errors were encountered: