我们的应用程序使用临时队列将服务总线响应定向到始发呼叫者。我们使用内置的ServiceStack.RabbitMq.RabbitMqServer
来发布和处理消息。
Message<IReturn<ResponseDto>> message = BuildMessage(requestDto);
// get the temporary queue for the current IMessageQueueClient
string queueName = messageclient.GetTempQueueName();
message.ReplyTo = queueName;
// publish the message
messageclient.Publish(message);
但是,如果调用抛出异常,则直接(下面)捕获响应将失败。
IMessage<ResponseDto> responseMessage = messageclient.Get<ResponseDto>(queueName, timeOut);
messageclient.Ack(responseMessage);
ResponseDto response = responseMessage.GetBody();
响应消息的正文将是ServiceStack.ErrorResponse
,导致responseMessage.GetBody()
返回一个空对象。并且错误不会返回为responseMessage.Error
。
我们通过将消息正文作为原始JSV字符串并验证结果来解决这个问题。
IMessage<string> responseMessage = messageclient.Get<string>(queueName, timeOut);
messageclient.Ack(responseMessage);
// get the body of the message as a string
string messageBody = responseMessage.GetBody();
// parse as error response
var error = messageBody.FromJsv<ErrorResponse>();
// if no response status, assume good
if (error?.ResponseStatus != null)
throw new Exception(error.ResponseStatus.Message);
// parse as response and return
return messageBody.FromJsv<ResponseDto>();
这适用于大多数情况,但是,如果返回的RabbitMq消息JSON中的字符串值包含逗号,则该字符串不包含在消息体JSV中的引号中(这似乎是ServiceStack.Text
中的问题从JSON转换时 - 使用JsonTypeSerializer
转换JSV
这导致该字段不完整,后续字段被忽略。
有没有更好的方法来检索异常?或者是否有序列化问题的解决方法?
答案 0 :(得分:2)
不应该将JSON转换为JSV,它们是不同的格式。 JSV使用CSV样式的编码和转义,这在JSON中是非法的,它要求引用所有字符串值并使用\
转义字符串。
基本上你应该使用确切的序列化程序和用于序列化它的类型来反序列化消息,如果你这样做应该没有任何问题。
ServiceStack's Rabbit MQ支持将复杂的Type有效负载序列化为JSON,因此不清楚JSV的来源。
如果需要访问原始文本有效负载,则应使用Rabbit MQ的低级API而不是ServiceStack的RabbitMQ高级API,这些API会自动尝试在幕后反序列化复杂类型的消息。
要获取原始文本正文,您可以执行以下操作:
var rabbitMqClient = messageclient as RabbitMqProducer;
var mqResult = rabbitMqClient.GetMessage(queueName, noAck: false);
var props = msgResult.BasicProperties;
var bodyString = msgResult.Body.FromUtf8Bytes(); //normally JSON