¿Cómo evitar incompatibilidades al deserializar propiedades polimórficas en MassTransit?
Al utilizar el patrón de solicitud/respuesta, durante la deserialización de la respuesta se produce un error de incompatibilidad. Aparentemente, la configuración de serialización del editor está causando este problema, aunque el mensaje es el esperado.
El uso de la función JsonProperty podría aislar el problema, sin embargo, no refleja lo que se esperaba.
Versiones
.NET: 6.0;
MassTRansit: 7.3.0;
Newtonsoft: 13.0.1
log
El tipo especificado en JSON ‘Messages.Models+CreditCard, Messages’ no es compatible con ‘GreenPipes.DynamicInternal.Models+Messages.Models+IPaymentMethod’.
Recurso:
c#
_bus.CreateRequestClient
Configuración de serializer del productor:
c#
bus.ConfigureJsonSerializer(settings =>
{
settings.TypeNameHandling = TypeNameHandling.Objects;
return settings;
});
Serialización de la respuesta del mensaje:
“`json
{
"message": {
"$type": "Messages.Services.ShoppingCarts.Responses+CartDetails, Messages",
"cartItems": [
{
"$type": "Messages.Models+Item, Messages",
"productId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"productName": "string",
"unitPrice": "10.0",
"quantity": 30,
"pictureUrl": "string"
}
],
"paymentMethods": [
{
"$type": "Messages.Models+CreditCard, Messages",
"id": "be7c40ac-1cd1-4e35-bccf-a1a2f4efecfd",
"expiration": "01/22",
"holderName": "string",
"number": "374245455400126",
"securityNumber": "string"
},
{
"$type": "Messages.Models+PayPal, Messages",
"id": "9465cf12-a322-477d-94c8-116d03a8399e",
"Password": "123",
"UserName": "string"
}
],
…
Configuración de <strong>deserializer</strong> del consumidor:
c#
bus.ConfigureJsonDeserializer(settings =>
{
settings.TypeNameHandling = TypeNameHandling.Objects; // o Auto, All, etc…
return settings;
});
Error:
log
System.Runtime.Serialization.SerializationException: Se produjo una excepción de serialización JSON durante la deserialización del sobre del mensaje
—> Newtonsoft.Json.JsonSerializationException: El tipo especificado en JSON 'Messages.Models+CreditCard, Messages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' no es compatible con 'GreenPipes.DynamicInternal.Models+Messages.Models+IPaymentMethod, MessagesGreenPipes.DynamicInternale7ccc67139ad479db488c4fa6310335a, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Camino 'message.paymentMethods[0].$type', línea 30, posición 55.
JsonProperty no funciona:
c#
public record CartDetails : Response
{
[JsonProperty(TypeNameHandling = TypeNameHandling.Objects)]
public IEnumerable<models.ipaymentmethod> PaymentMethods { get; init; }
}
“`json
{
“message”: {
"cartItems": [
{
"productId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"productName": "string",
"unitPrice": "10.0",
"quantity": 30,
"pictureUrl": "string"
}
],
"paymentMethods": [
{
"id": "be7c40ac-1cd1-4e35-bccf-a1a2f4efecfd",
"expiration": "01/22",
"holderName": "string",
"number": "374245455400126",
"securityNumber": "string"
},
{
"id": "9465cf12-a322-477d-94c8-116d03a8399e",
"Password": "123",
"UserName": "string"
}
],
…
Respuesta
c#
public record CartDetails : Response
{
// [JsonProperty(TypeNameHandling = TypeNameHandling.Objects)]
public IEnumerable<models.ipaymentmethod> PaymentMethods { get; init; }
public IEnumerable<models.item> CartItems { get; init; }
public Guid UserId { get; init; }
public decimal Total { get; init; }
public Guid Id { get; init; }
public bool IsDeleted { get; init; }
}
Tipos:
“`c#
public interface IPaymentMethod
{
Guid Id { get; }
decimal Amount { get; }
}
public record CreditCard : IPaymentMethod
{
public Guid Id { get; init; }
public decimal Amount { get; init; }
[property: JsonConverter(typeof(ExpirationDateOnlyJsonConverter))]
public DateOnly Expiration { get; init; }
public string HolderName { get; init; }
public string Number { get; init; }
public string SecurityNumber { get; init; }
}
public record PayPal : IPaymentMethod
{
public Guid Id { get; init; }
public decimal Amount { get; init; }
public string UserName { get; init; }
public string Password { get; init; }
}
“`</models.item></models.ipaymentmethod></models.ipaymentmethod>
davy.ai
El error ocurre durante la deserialización de una respuesta en un patrón de solicitud/respuesta, donde se informa un error de incompatibilidad aunque el mensaje es el esperado. El problema es causado por la configuración del serializador del publicador, específicamente la configuración
settings.TypeNameHandling
establecida enTypeNameHandling.Objects
. La configuración del deserializador del consumidor debe coincidir con la configuración del serializador del publicador, de lo contrario, pueden ocurrir errores como este.Una posible solución para aislar el problema es usar la funcionalidad
JsonProperty
para establecerTypeNameHandling
enTypeNameHandling.Objects
solo para la propiedad problemática. Sin embargo, este método puede no reflejar el comportamiento esperado.Las versiones utilizadas en el ejemplo son .NET 6.0, MassTRansit 7.3.0 y Newtonsoft 13.0.1.
El mensaje de error proporcionado indica que el tipo especificado en el JSON no es compatible con el tipo esperado. La funcionalidad
JsonProperty
no funciona ya que solo se aplica a la serialización, no a la deserialización.Para solucionar este problema, asegúrese de que la configuración del deserializador del consumidor coincida con la configuración del serializador del publicador. En el ejemplo proporcionado, ambos deben establecer
TypeNameHandling
enTypeNameHandling.Objects
.