c# - 在 Azure 逻辑应用程序中反序列化 ServiceBus 内容

标签 c# json servicebus azure-logic-apps

我正在尝试读取 Azure 逻辑应用程序中消息的内容正文,但没有取得太大成功。我看到很多建议说body是base64编码的,建议用下面的解码:

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

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

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

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

InvalidTemplate. Unable to process template language expressions in action 'HTTP' inputs at line '1' and column '2451': 'The template language function 'json' parameter is not valid. The provided value @string3http://schemas.microsoft.com/2003/10/Serialization/�3{"Foo":"bar" } cannot be parsed: Unexpected character encountered while parsing value: @. Path '', line 0, position 0.. Please see https://aka.ms/logicexpressions#json for usage details.'.

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

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

如何在我的逻辑应用程序中将其正确读取为 JSON 对象?

最佳答案

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

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

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

Initializes a new instance of the BrokeredMessage class from a given object by using DataContractSerializer with a binary XmlDictionaryWriter.

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

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

  • 确保接收方可以处理二进制 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);

关于c# - 在 Azure 逻辑应用程序中反序列化 ServiceBus 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50223133/

相关文章:

javascript - 将 JSON 放入 JSON 中

javascript - ajax成功时过滤json的Key值

msmq - nServiceBus、公共(public)交通、Rhino 服务总线、其他?

json - Spring @ResponseBody Jackson JsonSerializer 与 JodaTime

azure - Azure ServiceBus 上的 SqlFilter 主题订阅未过滤

servicebus - Microsoft Service Bus 1.0 无法与客户端域外的服务器通信

c# - C#访问字段集控件的方法

c# - 从列表中获取不同的属性值

c# - 使用 ASP.Net MVC 5 和 Web API 2.0 在 OData 中进行 Dictionary<string, object> 序列化

c# - 如何解决 Asp.Net 3.0 将数据库从 SQLite 迁移到 MySQL 的问题?