Naively, I thought I could simply decode the body as a string. I was wrong.
I would get the error:
Exception while executing function: Functions.OnOrderCreated. mscorlib: Exception has been thrown by the target of an invocation. System.Runtime.Serialization: Expecting element 'string' from namespace 'http://schemas.microsoft.com/2003/10/Serialization/'.. Encountered 'Element' with name 'base64Binary', namespace 'http://schemas.microsoft.com/2003/10/Serialization/'. .
After an investigation, I discovered that NServiceBus sets the property NServiceBus.Transport.Encoding to the value wcf/byte-array.
The message body looks like this:
<base64Binary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">77u/eyJBbGxvY2F0aW9uSWQiOiIx...... Simplified ....</base64Binary>
and if you base 64 decode the element content and encode using UTF8 you get the following output in the debugger window:
{"AllocationId":"18475fa4-c696-4992-a559-f48b7cab4cab","CreatedDate":"2017-02-10T11:18:03.7281344+00:00","CurrencyCode":"GBP","SizeSchema":"UK","Products":..... Simplified .... }
However if you then try and use JSONConvert to deseriaize it into a typed object, it errors with:
"Unexpected character encountered while parsing value: . Path '', line 0, position 0."
This is because there are a hidden three bytes which are not shown in the debugger window but which are shown if you look at the byte array. The three bytes are the Byte Order Mark: EF BB BF (239 187 191). These need to be stripped out.
The code below - used in Linqpad - demonstrates a way of getting at the inner content.
void Main()
{
Uri uri = ServiceBusEnvironment.CreateServiceUri("sb", "mytest", string.Empty);
string topicName = "bundle-1";
string subscriptionName = "Linqpad";
string name = "RootManageSharedAccessKey";
string key = "";
string connectionString = "Endpoint=sb://mytest.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=";
TokenProvider tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(name, key);
NamespaceManager namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);
SubscriptionClient Client = SubscriptionClient.CreateFromConnectionString(connectionString, topicName, subscriptionName);
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = false;
options.AutoRenewTimeout = TimeSpan.FromMinutes(1);
Client.OnMessage((message) =>
{
try
{
// Console.WriteLine("Transport encoding: " + message.Properties["NServiceBus.Transport.Encoding"]);
var xml = message.GetBody();
var body = Convert.FromBase64String(xml.InnerText);
var contentWithBom = Encoding.UTF8.GetString(body);
// content.Dump();
// Remove the BOM from the string
var contentWithoutBom = Encoding.UTF8.GetString(body, 3, body.Length - 3);
Console.WriteLine(contentWithoutBom);
var orderCreated = JsonConvert.DeserializeObject(contentWithoutBom);
orderCreated.Dump();
}
catch (Exception error)
{
error.Dump();
// Indicates a problem, unlock message in subscription.
message.Abandon();
}
}, options);
string input = "";
Console.WriteLine("Press x to stop");
while (!input.ToLower().StartsWith("x"))
{
input = Console.ReadLine();
}
}
https://github.com/Particular/NServiceBus.AzureServiceBus/issues/8
https://github.com/Particular/NServiceBus.AzureServiceBus/issues/32
No comments:
Post a Comment