C# 配置MassTransit以反序列化多态属性

C# 配置MassTransit以反序列化多态属性,c#,serialization,masstransit,C#,Serialization,Masstransit,因此,我们正在发送一条由复杂域类型组成的消息。我们的消费者没有触发,因为MassTransit无法反序列化消息并委托给消费者 此场景可以通过以下方式演示: // message interface public interface ITestMessage { TestBaseClass Data { get; set; } }; // message implementation public class TestMessage : ITestMessage { public Tes

因此,我们正在发送一条由复杂域类型组成的消息。我们的消费者没有触发,因为MassTransit无法反序列化消息并委托给消费者

此场景可以通过以下方式演示:

// message interface
public interface ITestMessage { TestBaseClass Data { get; set; } };

// message implementation
public class TestMessage : ITestMessage
{
    public TestBaseClass Data { get; set; }
}

// abstract child
public abstract class TestBaseClass { }

// a concrete implementation of abstract child, cannot be deserialized 
// by default serializer configuration
public class TestConcreteClass : TestBaseClass { }

// simple consumer, uses a reset-event to synchronize with calling
// test method
public class TestConsumer : IConsumer<ITestMessage>
{
    private readonly Action action = null;
    public TestConsumer(Action action) { this.action = action; }
    public Task Consume(ConsumeContext<ITestMessage> context)
    {
        action();
        return context.CompleteTask;
    }
}

[TestMethod]
public void Publish_WhenPolymorphicMessage_ConsumesMessage()
{
    ManualResetEvent isConsumed = new ManualResetEvent(false);
    IBusControl bus = Bus.Factory.CreateUsingInMemory(c =>
    {
        InMemoryTransportCache inMemoryTransportCache = 
            new InMemoryTransportCache(Environment.ProcessorCount);
        c.SetTransportProvider(inMemoryTransportCache);
        c.ReceiveEndpoint(
            "", 
            e => e.Consumer<TestConsumer>(
                () => new TestConsumer(() => isConsumed.Set())));
    });
    bus.Start();

    ITestMessage message = new TestMessage 
    {
        // comment out assignment below, et voila, we pass :S
        Data = new TestConcreteClass { },
    };

    // attempt to publish message and wait for consumer
    bus.Publish<ITestMessage>(message);

    // simple timeout fails
    Assert.IsTrue(isConsumed.WaitOne(TimeSpan.FromSeconds(5)));
}
我尝试了各种配置,但没有成功

IBusControl bus = Bus.Factory.CreateUsingInMemory(c =>
{
    InMemoryTransportCache inMemoryTransportCache = 
        new InMemoryTransportCache(Environment.ProcessorCount);
    c.SetTransportProvider(inMemoryTransportCache);

    // attempt to set and configure json serializer; zero effect
    c.ConfigureJsonDeserializer(
        s => 
        {
            s.TypeNameHandling = TypeNameHandling.All; 
            return s;
        });
    c.ConfigureJsonSerializer(
        s => 
        {
            s.TypeNameHandling = TypeNameHandling.All; 
            return s; 
        });
    c.UseJsonSerializer();

    c.ReceiveEndpoint(
        "", 
        e => e.Consumer<TestConsumer>(
            () => new TestConsumer(() => isConsumed.Set())));
});
IBusControl总线=bus.Factory.CreateUsingInMemory(c=>
{
InMemoryTransportCache InMemoryTransportCache=
新的InMemoryTransportCache(Environment.ProcessorCount);
c、 SetTransportProvider(inMemoryTransportCache);
//尝试设置和配置json序列化程序;零效果
c、 配置JSONDESerializer(
s=>
{
s、 TypeNameHandling=TypeNameHandling.All;
返回s;
});
c、 配置JSONSerializer(
s=>
{
s、 TypeNameHandling=TypeNameHandling.All;
返回s;
});
c、 使用JSONSerializer();
c、 接收端点(
"", 
e=>e.消费者(
()=>newtestconsumer(()=>isConsumed.Set());
});

我正在寻找任何成功的解决方案,例如使用
KnownType
属性装饰消息/域类,或总线配置。任何能够成功通过上述测试方法的操作。

将您的
ITestMessage
接口声明更改为:

// message interface
public interface ITestMessage
{
    [JsonProperty(TypeNameHandling = TypeNameHandling.Objects)]
    TestBaseClass Data { get; set; }
};

为我解决了这个问题。

我将引用以下内容:并指出,当您尝试使用行为序列化类时,您会遇到麻烦。@Chris Patterson,不适用。我们不是基于内容的路由,这是愚蠢的负载。纯序列化。如果下面的解决方案对您有效,请关闭此问题-谢谢。单元测试:谢谢!很抱歉反应迟缓,但有效,现已被接受!
// message interface
public interface ITestMessage
{
    [JsonProperty(TypeNameHandling = TypeNameHandling.Objects)]
    TestBaseClass Data { get; set; }
};