在Azure Logic App中反序列化ServiceBus内容

我正在尝试在Azure Logic App中阅读邮件的内容正文,但我没有取得多大成功。 我已经看到很多建议说机体是base64编码的,并建议使用以下代码进行解码:

@{json(base64ToString(triggerBody()?['ContentData']))} 

base64ToString(...)部分正在将内容正确解码为字符串,但字符串似乎包含一个前缀,在开头有一些额外的序列化信息:

 @string3http://schemas.microsoft.com/2003/10/Serialization/ 3{"Foo":"Bar"} 

该字符串中还有一些额外的字符未在我的浏览器中显示。 所以json(...)函数不接受输入,而是给出错误。

InvalidTemplate。 无法在第1行和第2451行的“HTTP”输入中处理模板语言表达式:’模板语言函数’json’参数无效。 提供的值@string3http://schemas.microsoft.com/2003/10/Serialization/ 3{"Foo":"bar" }无法解析: Unexpected character encountered while parsing value: @. Path '', line 0, position 0. Unexpected character encountered while parsing value: @. Path '', line 0, position 0. 。 有关使用详情,请参阅https://aka.ms/logicexpressions#json 。’。

作为参考,使用.NET服务总线客户端将消息添加到主题中(客户端应该无关紧要,但这看起来更像C#-ish):

 await TopicClient.SendAsync(new BrokeredMessage(JsonConvert.SerializeObject(item))); 

如何在Logic App中将其正确读取为JSON对象?

您可以将substring函数与indexOflastIndexOf一起使用,以仅获取JSON子字符串。

不幸的是,它相当复杂,但看起来应该是这样的:

 @json(substring(base64ToString(triggerBody()?['ContentData']), indexof(base64ToString(triggerBody()?['ContentData']), '{'), add(1, sub(lastindexof(base64ToString(triggerBody()?['ContentData']), '}'), indexof(base64ToString(triggerBody()?['ContentData']), '}'))))) 

有关如何在这里使用这些function的更多信息。

HTH

由消息放置在ServiceBus上的方式引起的,特别是在C#代码中。 我使用以下代码添加新消息:

 var json = JsonConvert.SerializeObject(item); var message = new BrokeredMessage(json); await TopicClient.SendAsync(message); 

这段代码看起来很好,并且在不同的C#服务之间工作没问题。 问题是由BrokeredMessage(Object)构造函数序列化给它的有效负载的方式引起的:

通过使用带有二进制XmlDictionaryWriter的DataContractSerializer,从给定对象初始化BrokeredMessage类的新实例。

这意味着内容被序列化为二进制XML,它解释了前缀和无法识别的字符。 在反序列化时,C#实现会隐藏它,并返回您期望的对象,但在使用不同的库(例如Azure Logic Apps使用的库)时会变得明显。

有两种方法可以解决这个问题:

  • 确保接收器可以处理二进制XML格式的消息
  • 确保发件人实际使用我们想要的格式,例如JSON。

Paco de la Cruz的答案处理第一种情况,使用substringindexOflastIndexOf

 @json(substring(base64ToString(triggerBody()?['ContentData']), indexof(base64ToString(triggerBody()?['ContentData']), '{'), add(1, sub(lastindexof(base64ToString(triggerBody()?['ContentData']), '}'), indexof(base64ToString(triggerBody()?['ContentData']), '}'))))) 

至于第二种情况,在源处修复问题只需使用BrokeredMessage(Stream)构造函数。 这样,我们可以直接控制内容:

 var json = JsonConvert.SerializeObject(item); var bytes = Encoding.UTF8.GetBytes(json); var stream = new MemoryStream(bytes); var message = new BrokeredMessage(stream, true); await TopicClient.SendAsync(message); 
Interesting Posts