我正在编写两小段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标头传递它。

10-06 14:30