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