我希望能够在一个队列上发送两个不同的JSON消息。我如何在C#中确定收到的消息类型,以便我可以将消息反序列化为正确的对象?我应该使用邮件头还是创建另一个队列?每种消息类型的队列对我来说似乎过分。谢谢!
额外细节: 我有一个处理“运行”的Windows服务。运行ID由另一个系统分配,ID将被删除到队列中。我的服务拿起ID并开始工作。为每次运行创建一个对象。现在,如果我想取消工作,我必须停止服务。但是,这会阻止所有工作。我想添加一个CancelRun类型的方法,但我只需要运行ID。所以,我可以使用完全相同的JSON(所以相同的类)。两个队列不会很糟糕,但我认为将类型或内容添加到自定义标题可能很聪明。
答案 0 :(得分:3)
这就是我的用途。我喜欢这种技术,因为我没有向不属于模型的JSON添加内容。
IBasicProperties props = model.CreateBasicProperties();
props.Headers = new Dictionary<string, object>();
props.Headers.Add("RequestType", "CancelRunRequest");
然后,在接收方,我这样做(我正在使用自定义EventArg obj引发事件):
// Raise message received event
var args = new MessageReceivedArgs();
args.CorrelationId = response.BasicProperties.CorrelationId;
args.Message = Encoding.UTF8.GetString(response.Body);
args.Exchange = response.Exchange;
args.RoutingKey = response.RoutingKey;
if (response.BasicProperties.Headers != null && response.BasicProperties.Headers.ContainsKey("RequestType"))
{
args.RequestType = Encoding.UTF8.GetString((byte[])response.BasicProperties.Headers["RequestType"]);
}
MessageReceived(this, args);
model.BasicAck(response.DeliveryTag, false);
项目的其他地方:
private void NewRunIdReceived(object p, MessageReceivedArgs e)
{
if(e.RequestType.ToUpper() == "CANCELRUNREQUEST")
{
// This is a cancellation request
CancelRun(e);
}
else
{
// Default to startrun request for backwards compatibility.
StartRun(e);
}
}
答案 1 :(得分:1)
如果订单或接收和处理这些消息不是问题,我建议为每种类型使用单独的队列,兔子处理大量队列不是问题。 如果没有,订单对您来说至关重要,您可以将标记放在定义其类型的消息的标题中,但这会将您的业务逻辑与传输层绑定。如果您希望稍后在应用程序中更改传输层,则必须采用此部分代码才能使其正常工作。除此之外,您可以为这两种隐藏内部内容的对象类型制作某种包装,看起来相同,并且可以在其包含的类型中对自身进行脱盐。
答案 2 :(得分:0)
JSON没有说明序列化的类型,除非序列化程序本身向JSON添加了一些信息。
您可以向JSON添加一些结构,以便您可以扣除类型。
答案 3 :(得分:0)
您可以将所有这些添加到数组中,然后根据类型进行反序列化,您必须手动添加type属性,或者您可以创建Object IHaveType,然后在正在使用的对象中继承它,但是&#39;这是一种可怕的方式。
ObjectType1 : HaveType
public class HaveType { public string Type { get { this.GetType(); }}}
Json
[{Type: 'ObjectType1', ...[other object stuff]},{Type : 'ObjectType2',...}]
答案 4 :(得分:0)
按照sphair的建议添加运行时类型信息,但我不喜欢这样做,因为你失去了弱类型的可移植性值。您也可以考虑让反序列化的C#对象具有足够的通用性来处理所有的风格,然后从那里进行分支。