我正在编写两小段C#代码。第一个是针对客户端可移植类库的。它所做的只是使用Azure Service Bus REST API通过HttpClient将消息发送到Azure Service Bus主题。
我使用有效的JSON填充REST调用中的BrokerProperties header,并且希望在服务器端,当我通过订阅收到消息时,我将获得BrokeredMessage.Properties实例,该实例中填充了我发送的值客户端。
我在这方面遇到的一个问题是文档说将Content-Type设置为application/atom+xml;type=entry;charset=utf-8
,但是即使我得到了application/json; charset=utf-8
,我也只使用了application/json
。
顺便说一句,据我所知,这确实应该做。它创建客户端和请求消息,设置标题,然后发送消息。我得到201创建每次。这就是全部:
private async static void SendServiceBusMessage(Command command)
{
// Create the HttpClient and HttpRequestMessage objects
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, topicUri);
// Add the authorization header (CreateAuthToken does the SHA256 stuff)
request.Headers.Add("Authorization", CreateAuthToken(topicUri, authSasKeyName, authSasKey));
// Add the content (command is a normal POCO)
// I've tried application/atom+xml;type=entry;charset=utf-8, always see application/json in the request
request.Content = new StringContent(JsonConvert.SerializeObject(command), Encoding.UTF8, "application/json");
// Add the command name and SessionId as BrokeredMessage properties
var brokeredMessageProperties = new Dictionary<string, string>();
brokeredMessageProperties.Add("CommandName", command.GetType().Name);
brokeredMessageProperties.Add("SessionId", Guid.NewGuid().ToString());
// Add the BrokerProperties header to the request
request.Content.Headers.Add("BrokerProperties", JsonConvert.SerializeObject(brokeredMessageProperties));
// I've also tried adding it directly to the request, nothing seems different
// request.Headers.Add("BrokerProperties", JsonConvert.SerializeObject(brokeredMessageProperties));
// Send it
var response = await client.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
// Do some error-handling
}
}
这是它发送的HTTP请求的示例。将其与Send Message文档底部的示例进行比较...除了Content-Type,它在功能上看起来与我相同。
POST https://myawesomesbnamespace.servicebus.windows.net/commands/messages HTTP/1.1
Authorization: SharedAccessSignature sr=https%3A%2F%2Fmyawesomesbnamespace.servicebus.windows.net%2Fcommands%2Fmessages&sig=SomeValidAuthStuffHere
Content-Type: application/json; charset=utf-8
BrokerProperties: {"CommandName":"CreateJob_V1","SessionId":"94932660-54e9-4867-a020-883a9bb79fa1"}
Host: myawesomesbnamespace.servicebus.windows.net
Content-Length: 133
Expect: 100-continue
Connection: Keep-Alive
{"JobId":"6b76e7e6-9499-4809-b762-54c03856d5a3","Name":"Awesome New Job Name","CorrelationId":"47fc77d9-9470-4d65-aa7d-690b65a7dc4f"}
但是,当我在服务器上收到消息时,.Properties为空。真烦人
服务器代码如下所示。它只是获取一批消息并执行foreach循环。
private async Task ProcessCommandMessages()
{
List<BrokeredMessage> commandMessages = (await commandsSubscriptionClient.ReceiveBatchAsync(serviceBusMessageBatchSize, TimeSpan.FromMilliseconds(waitTime_ms))).ToList();
foreach (BrokeredMessage commandMessage in commandMessages)
{
// commandMessage.Properties should have CommandName and SessionId,
// like I sent from the client, but it's empty
// that's not good
if (commandMessage.Properties.ContainsKey("CommandName"))
{
string commandName = commandMessage.Properties["CommandName"] as string;
// Do some stuff
}
else
{
// This is bad, log an error
}
}
}
所以,我有点卡住了。有人可以在这里发现我做错了吗?也许是Content-Type问题,并且有解决方法?
谢谢!
史考特
美国华盛顿州西雅图
最佳答案
好的,最后回到这个问题。我误解了(我认为文档尚不清楚)是不能通过BrokerProperties标头传递任意属性。只有BrokeredMessage类中的命名属性(如SessionId,Label等)将通过Service Bus到达服务器。
为了使属性显示在BrokeredMessage.Properties中,必须在请求上将它们作为自定义标头传递。所以,就我而言
request.Headers.Add("CommandName", command.GetType().Name);
通过服务总线传递消息后,获取CommandName属性以显示在服务器上。
为了传递SessionId值,我仍然要通过BrokerProperties标头传递它。