当 ReplyTo 是临时队列时检索异常
Retrieving exceptions when ReplyTo is a temp queue
我们的应用程序使用临时队列将服务总线响应定向到原始调用方。我们使用内置的 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()
到 return 一个空对象。并且错误未 return 编辑为 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>();
这适用于大多数情况,但是,如果 returning RabbitMq 消息 JSON 中的字符串值包含逗号,则该字符串不包含在消息正文 JSV 的引号中(这使用 JsonTypeSerializer
从 JSON -> JSV 转换时似乎是 ServiceStack.Text
中的一个问题)
这导致该字段不完整,随后的字段被忽略。
是否有更好的方法来检索异常?或者是否有序列化问题的解决方法?
不应将 JSON 转换为 JSV,它们是不同的格式。 JSV 使用 CSV 风格的编码和转义,这在 JSON 中是非法的,它要求所有字符串值都被引用并且字符串用 \
.
转义
本质上,您应该使用用于序列化消息的确切序列化程序和类型来反序列化消息,如果您这样做,应该不会有任何问题。
ServiceStack's Rabbit MQ 支持将复杂类型的有效负载序列化为 JSON,因此不清楚 JSV 的来源。
如果您需要访问原始文本负载,您应该使用 Rabbit MQ 的低级 API 而不是 ServiceStack 的 RabbitMQ 高级 API,后者会自动尝试在幕后反序列化复杂类型的消息。
要获取原始文本正文,您可以执行以下操作:
var rabbitMqClient = messageclient as RabbitMqProducer;
var mqResult = rabbitMqClient.GetMessage(queueName, noAck: false);
var props = msgResult.BasicProperties;
var bodyString = msgResult.Body.FromUtf8Bytes(); //normally JSON
我们的应用程序使用临时队列将服务总线响应定向到原始调用方。我们使用内置的 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()
到 return 一个空对象。并且错误未 return 编辑为 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>();
这适用于大多数情况,但是,如果 returning RabbitMq 消息 JSON 中的字符串值包含逗号,则该字符串不包含在消息正文 JSV 的引号中(这使用 JsonTypeSerializer
从 JSON -> JSV 转换时似乎是 ServiceStack.Text
中的一个问题)
这导致该字段不完整,随后的字段被忽略。
是否有更好的方法来检索异常?或者是否有序列化问题的解决方法?
不应将 JSON 转换为 JSV,它们是不同的格式。 JSV 使用 CSV 风格的编码和转义,这在 JSON 中是非法的,它要求所有字符串值都被引用并且字符串用 \
.
本质上,您应该使用用于序列化消息的确切序列化程序和类型来反序列化消息,如果您这样做,应该不会有任何问题。
ServiceStack's Rabbit MQ 支持将复杂类型的有效负载序列化为 JSON,因此不清楚 JSV 的来源。
如果您需要访问原始文本负载,您应该使用 Rabbit MQ 的低级 API 而不是 ServiceStack 的 RabbitMQ 高级 API,后者会自动尝试在幕后反序列化复杂类型的消息。
要获取原始文本正文,您可以执行以下操作:
var rabbitMqClient = messageclient as RabbitMqProducer;
var mqResult = rabbitMqClient.GetMessage(queueName, noAck: false);
var props = msgResult.BasicProperties;
var bodyString = msgResult.Body.FromUtf8Bytes(); //normally JSON