es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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().GetResponse(message, cancellationToken);

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>

Tags:  , , ,

Answer

  1. Avatar for 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 en TypeNameHandling.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 establecer TypeNameHandling en TypeNameHandling.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 en TypeNameHandling.Objects.

Comments are closed.