问题
I keep recieving the following message from my denormalizer host after publishing an event in my domain:
2011-07-22 14:18:32,374 [Worker.5] WARN NServiceBus.Unicast.UnicastBus [(null)]
<(null)> - Received an empty message - ignoring.
I am just doing this with jolivers eventstore:
return Wireup.Init()
.UsingRavenPersistence("EventStore", new DocumentObjectSerializer())
.UsingAsynchronousDispatcher()
.PublishTo(new DelegateMessagePublisher(c => container.Resolve<IPublishMessages>().Publish(c)))
.Build();
IPublishMessages resolves to :
public sealed class NServiceBusPublisher : IPublishMessages
{
private const string AggregateIdKey = "AggregateId";
private const string CommitVersionKey = "CommitVersion";
private const string EventVersionKey = "EventVersion";
private const string BusPrefixKey = "Bus.";
private readonly IBus bus;
public NServiceBusPublisher(IBus bus)
{
this.bus = bus;
}
public void Dispose()
{
GC.SuppressFinalize(this);
}
public void Publish(Commit commit)
{
for (var i = 0; i < commit.Events.Count; i++)
{
var eventMessage = commit.Events[i];
var busMessage = eventMessage.Body as IMessage;
AppendHeaders(busMessage, commit.Headers); // optional
AppendHeaders(busMessage, eventMessage.Headers); // optional
AppendVersion(commit, i); // optional
this.bus.Publish(busMessage);
}
}
private static void AppendHeaders(IMessage message, IEnumerable<KeyValuePair<string, object>> headers)
{
headers = headers.Where(x => x.Key.StartsWith(BusPrefixKey));
foreach (var header in headers)
{
var key = header.Key.Substring(BusPrefixKey.Length);
var value = (header.Value ?? string.Empty).ToString();
message.SetHeader(key, value);
}
}
private static void AppendVersion(Commit commit, int index)
{
var busMessage = commit.Events[index].Body as IMessage;
busMessage.SetHeader(AggregateIdKey, commit.StreamId.ToString());
busMessage.SetHeader(CommitVersionKey, commit.StreamRevision.ToString());
busMessage.SetHeader(EventVersionKey, GetSpecificEventVersion(commit, index).ToString());
}
private static int GetSpecificEventVersion(Commit commit, int index)
{
// e.g. (StreamRevision: 120) - (5 events) + 1 + (index @ 4: the last index) = event version: 120
return commit.StreamRevision - commit.Events.Count + 1 + index;
}
}
The NServiceBus host that is publishing the events has the following config:
<MsmqTransportConfig
InputQueue="SonatribeInputQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig
DistributorControlAddress=""
DistributorDataAddress=""
ForwardReceivedMessagesTo="">
<MessageEndpointMappings>
<add Messages="Events" Endpoint="SonatribeInputQueue"/>
</MessageEndpointMappings>
</UnicastBusConfig>
And the denormalizer host recieving the events is:
<MsmqTransportConfig
InputQueue="MyServerInputQueue"
ErrorQueue="error"
NumberOfWorkerThreads="1"
MaxRetries="5"
/>
<UnicastBusConfig>
<MessageEndpointMappings>
<add Messages="Events" Endpoint="SonatribeInputQueue"/>
</MessageEndpointMappings>
</UnicastBusConfig>
Which seems about right to me - the publisher processes the command sent from the web and the domain raises the event. the NServiceBusPublisher publishes the event and the denormalizer host at least recieves something! it's just not the message it had been sent - or something has happened at least for it to think that the message is empty....
Anyone?
*****update***********
I am now getting the following from l4n:
2011-07-22 16:31:30,646 [Worker.7] ERROR NServiceBus.Faults.InMemory.FaultManage
r [(null)] <(null)> - Serialization failed for message with ID 56b7b693-090f-49b
d-83ad-7beeb334fe6d\12639.
System.Security.VerificationException: Operation could destabilize the runtime.
at SetId(Object , Object )
at NServiceBus.Serializers.XML.MessageSerializer.GetObjectOfTypeFromNode(Type
t, XmlNode node) in c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Seriali
zers.XML\MessageSerializer.cs:line 343
at NServiceBus.Serializers.XML.MessageSerializer.Process(XmlNode node, Object
parent) in c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Serializers.XML\
MessageSerializer.cs:line 330
at NServiceBus.Serializers.XML.MessageSerializer.Deserialize(Stream stream) i
n c:\Dev\NServiceBus\src\impl\Serializers\NServiceBus.Serializers.XML\MessageSer
ializer.cs:line 267
at NServiceBus.Unicast.UnicastBus.Extract(TransportMessage m) in c:\Dev\NServ
iceBus\src\unicast\NServiceBus.Unicast\UnicastBus.cs:line 851
2011-07-22 16:31:30,908 [Worker.7] WARN NServiceBus.Unicast.UnicastBus [(null)]
<(null)> - Received an empty message - ignoring.
Here is the message it is trying to deserialize!!
[Serializable]
public class AccountCreatedEvent : IEvent
{
public readonly string Id;
public readonly string Name;
public AccountCreatedEvent()
{
}
public AccountCreatedEvent(string id, string name)
{
this.Id = id;
this.Name = name;
}
public override string ToString()
{
return "AccountCreatedEvent - for when you've created an account";
}
}
not exactly anything hectic...
回答1:
It is clear why that message cannot be deserialized - you've got readonly properties. If you want to have this work, you need to switch to public get/set properties. In order to preserve your intent of not-publicly-changeable properties, here's an alternative approach:
[Serializable]
public class AccountCreatedEvent : IEvent
{
public string Id { get; private set; }
public string Name {get; private set; }
public AccountCreatedEvent(string id, string name)
{
this.Id = id;
this.Name = name;
}
public override string ToString()
{
return "AccountCreatedEvent - for when you've created an account";
}
}
来源:https://stackoverflow.com/questions/6790712/nservicebus-publishing-event-recieves-empty-message