当前位置: 首页 > 知识库问答 >
问题:

Azure服务总线无法接收JSON体

万俟渝
2023-03-14

调试此代码时,应用程序停止。未显示任何错误消息或异常。

项目X:

client.OnMessage((message) =>
{
    using (var stream = message.GetBody<Stream>())
    using (var streamReader = new StreamReader(stream, Encoding.UTF8))
    {
        var body = streamReader.ReadToEnd();
    }
 }

下面我将通过REST API发布JSON对象。

项目Y:

public void CreateMessage<T>(T messageToSend, string queueAddress, WebClient webclient)
{
    var apiVersion = "&api-version=2014-01";
    var serializedMessage = JsonConvert.SerializeObject(messageToSend, Formatting.Indented);
    string receivedMessageBody = webclient.UploadString(queueAddress + "/messages" + "?timeout=60&" + apiVersion, "POST", serializedMessage);

}

有办法找到尸体吗?

共有1个答案

欧阳子石
2023-03-14

根据您的描述,我检查了这个问题,并按照Send Message将我的消息发送到服务总线队列。

对于content-typeapplication/atom+xml;type=entry;charset=utf-8,需要使用带有二进制XmlDictionaryWriter的DataContractSerializer序列化负载。因此您需要按照以下方式构建有效负载:

定义您的对象并发送以下消息:

[DataContract]
public class DemoMessage
{
    [DataMember]
    public string Title { get; set; }
}

wc.Headers["Content-Type"] = "application/atom+xml;type=entry;charset=utf-8";
MemoryStream ms = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(typeof(DemoMessage));
serializer.WriteObject(ms, new DemoMessage() { Title = messageBody });
wc.UploadString(sendAddress, "POST",System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray()));

则可以使用以下代码接收消息:

var message = message.GetBody<DemoMessage>(new DataContractSerializer(typeof(DemoMessage)));

如果Content-Type指定为text/plain或未指定,则可以按如下方式序列化有效负载:

var messageBody = JsonConvert.SerializeObject(new DemoMessage(){ Title = messageBody }, Newtonsoft.Json.Formatting.Indented);
wc.UploadString(sendAddress, "POST", messageBody);

要接收消息,您可以使用下面的代码:

using (var stream = message.GetBody<Stream>())
{
    using (var streamReader = new StreamReader(stream, Encoding.UTF8))
    {
        msg = streamReader.ReadToEnd();
        var obj=JsonConvert.DeserializeObject<DemoMessage>(msg);
    }
}
static void Main(string[] args)
{   
    //send the message
    var wc = new WebClient();
    wc.Headers["Authorization"] = createToken("https://brucesb.servicebus.windows.net/order", "RootManageSharedAccessKey", "{your-key}");
    var messageBody = JsonConvert.SerializeObject(new DemoMessage() { Title = "hello world!!!!" }, Newtonsoft.Json.Formatting.Indented);
    wc.UploadString("https://brucesb.servicebus.windows.net/order/messages", "POST", messageBody);

    //receive the message
    QueueClient client = QueueClient.CreateFromConnectionString(connectionString, "order");
    client.OnMessage(message =>
    {
        using (var stream = message.GetBody<Stream>())
        {
            using (var streamReader = new StreamReader(stream, Encoding.UTF8))
            {
                var msg = streamReader.ReadToEnd();
                var obj = JsonConvert.DeserializeObject<DemoMessage>(msg);
                Console.WriteLine(msg);
            }
        }
    });
    Console.WriteLine("Press any key to exit...");
    Console.ReadLine();
}

static string createToken(string resourceUri, string keyName, string key)
{
    var expiry = (long)(DateTime.UtcNow.AddDays(1) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
    string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
    HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
    var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
    var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);
    return sasToken;
}

测试:

 类似资料:
  • 参考https://github.com/Azure/azure-service-bus/tree/master/samples/dotnet/gettingstart/microsoft.Azure.servicebus/basicsendreceiveusingtopicsubscriptionclient,我了解Azure服务总线主题的一般工作方式,我的问题更多地是关于它实际上是如何工作的。

  • 根据MS文档,从订阅接收消息并不困难。但是,如果我希望我的应用程序在每次发布新消息时都接收一条消息--一个恒定的轮询。因此,使用了SubscriptionClient类的OnMessage()方法。 MS文档说:“...当调用OnMessage时,客户端启动一个内部消息泵,该消息泵不断轮询队列或订阅。该消息泵由发出Receive()调用的无限循环组成。如果调用超时,它发出下一个Receive()调

  • 服务总线网关未启动。 首先,我尝试完全卸载所有Azure/Fabric/Service Bus类型的SDK和安装。我已经从头安装了和。 删除所有与服务总线相关的数据库后,我将启动服务总线配置向导,并开始使用自定义设置启动一个新场。 除了添加我自己的证书,当然还有输入我的密码之外,我保留所有的默认设置。 单击“开始”后,服务总线配置向导最终将卡在进程中: null 谢谢

  • null 输出 谁能解释一下为什么会这样吗?这对我来说有点迷惑?

  • 我希望以批处理模式接收来自Azure ServiceBus主题的消息。 阅读https://docs.microsoft.com/en-us/Azure/Azure-functions/functions-best-practices时指出: 我有一个方法: 这个方法是有效的,但它一次只需要一个消息。 根据Microsoft文档,我可以将其更改为: 注意:主题和订阅已启用“启用批处理操作”设置。

  • 我有一个超时选项,只想在超时前接收消息。 如果您能解释下面的代码是如何工作的,以及我如何修改下面的代码以在特定的时间框架内接收消息,并且一旦我的超时已经到达就停止接收,这将是很有帮助的。