diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index 1a712572da..099ff4c023 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -54,7 +54,7 @@
-
+
diff --git a/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs b/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs
new file mode 100644
index 0000000000..b6e807fd51
--- /dev/null
+++ b/src/ServiceControl.Audit.AcceptanceTests/Auditing/When_a_message_processed_with_receive_properties.cs
@@ -0,0 +1,100 @@
+namespace ServiceControl.Audit.AcceptanceTests.Auditing
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using AcceptanceTesting;
+ using AcceptanceTesting.EndpointTemplates;
+ using Audit.Auditing.MessagesView;
+ using NServiceBus;
+ using NServiceBus.AcceptanceTesting;
+ using NServiceBus.AcceptanceTesting.Customization;
+ using NServiceBus.Transport;
+ using NUnit.Framework;
+
+ class When_a_message_processed_with_receive_properties : AcceptanceTest
+ {
+ [Test]
+ public async Task Should_save_audit_message_with_receive_properties()
+ {
+ const string Payload = "PAYLOAD";
+ MessagesView auditedMessage = null;
+ byte[] body = null;
+
+ var context = await Define()
+ .WithEndpoint(b => b.When((bus, c) => bus.Send(new MyMessage { Payload = Payload })))
+ .WithEndpoint()
+ .Done(async c =>
+ {
+ if (c.MessageId == null)
+ {
+ return false;
+ }
+
+ var result = await this.TryGetSingle("/api/messages?include_system_messages=false&sort=id", m => m.MessageId == c.MessageId);
+ auditedMessage = result;
+ if (!result)
+ {
+ return false;
+ }
+
+ body = await this.DownloadData($"/api{auditedMessage.BodyUrl}");
+
+ return true;
+ })
+ .Run();
+
+ var hasReceivedProperties = auditedMessage.Headers.Any(x => x.Key.Equals("ServiceControl.ReceiveProperties.LearningTransport.FileCreatedAt"));
+
+ var receivedProperties = new KeyValuePair();
+ if (hasReceivedProperties)
+ {
+ receivedProperties = auditedMessage.Headers.First(x => x.Key.Equals("ServiceControl.ReceiveProperties.LearningTransport.FileCreatedAt"));
+ }
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(hasReceivedProperties, Is.True, "The audit message should have receive properties");
+ Assert.That(receivedProperties.Value, Is.EqualTo(context.ReceivedMessageFileCreatedAt), "The audit message should have receive properties");
+ }
+ }
+
+ public class Sender : EndpointConfigurationBuilder
+ {
+ public Sender() =>
+ EndpointSetup(c =>
+ {
+ var routing = c.ConfigureRouting();
+ routing.RouteToEndpoint(typeof(MyMessage), typeof(Receiver));
+ });
+ }
+
+ public class Receiver : EndpointConfigurationBuilder
+ {
+ public Receiver() => EndpointSetup();
+
+ [Handler]
+ public class MyMessageHandler(MyContext testContext) : IHandleMessages
+ {
+ public Task Handle(MyMessage message, IMessageHandlerContext context)
+ {
+ testContext.ReceivedMessageFileCreatedAt = context.Extensions.Get().ReceiveProperties["LearningTransport.FileCreatedAt"];
+ testContext.MessageId = context.MessageId;
+ return Task.Delay(500, context.CancellationToken);
+ }
+ }
+ }
+
+ public class MyMessage : ICommand
+ {
+ public string Payload { get; set; }
+ }
+
+ public class MyContext : ScenarioContext
+ {
+ public string MessageId { get; set; }
+
+ public string ReceivedMessageFileCreatedAt { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceControl.Audit/Auditing/AuditPersister.cs b/src/ServiceControl.Audit/Auditing/AuditPersister.cs
index f6089e2f28..6392c1444e 100644
--- a/src/ServiceControl.Audit/Auditing/AuditPersister.cs
+++ b/src/ServiceControl.Audit/Auditing/AuditPersister.cs
@@ -144,6 +144,11 @@ async Task ProcessAuditMessage(MessageContext context, IMessageDispatcher dispat
["MessageIntent"] = context.Headers.MessageIntent()
};
+ foreach (var property in context.ReceiveProperties)
+ {
+ context.Headers.TryAdd($"ServiceControl.ReceiveProperties.{property.Key}", property.Value);
+ }
+
var commandsToEmit = new List();
var messagesToEmit = new List();
var enricherContext = new AuditEnricherContext(context.Headers, commandsToEmit, messagesToEmit, metadata);