我创建了一个在特定时间运行的调度程序,并将JSON消息插入到存储队列中。 JSON消息是固定的,我在调度程序设置期间将其放在BODY
字段(表示text/plain
)中。消息是:
{ "action": "SendReminderMessages" }
在接收方(WebJob)上,我轮询队列,然后尝试反序列化这些消息中的JSON。而不是上面的预期JSON,我得到包装在XML消息中的JSON消息:
<?xml version="1.0" encoding="utf-16"?>
<StorageQueueMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ExecutionTag>(Some Hex String)</ExecutionTag>
<ClientRequestId>(Some GUID)</ClientRequestId>
<ExpectedExecutionTime>2015-09-17T07:00:00</ExpectedExecutionTime>
<SchedulerJobId>reminder-mails</SchedulerJobId>
<SchedulerJobCollectionId>scheduler-jobs</SchedulerJobCollectionId>
<Region>West Europe</Region>
<Message>{ "action": "SendReminderMessages" }</Message>
</StorageQueueMessage>
如何按原样发送JSON消息,即没有信封?
答案 0 :(得分:1)
Scheduler当前将一个XML包装器添加到正文中,作为传递作业元数据的方法。您可以使用正确反序列化消息的Scheduler SDK中的StorageQueueMessage类(在Microsoft.WindowsAzure.Scheduler.Models下)。 您可以投票选择Azure Scheduler功能,以添加不在我们的Azure Scheduler User Voice forum中包含包装器的功能。
答案 1 :(得分:0)
这听起来很奇怪,我只用电子邮件做同样的事情,它对我来说效果很好。我添加了我的代码,希望它能帮助你发现你的错误。
/// <summary>
/// Create or update a queue
/// </summary>
/// <param name="queueName">Name of queue</param>
/// <param name="message">Message to post in the queue</param>
/// <returns>Return true on success, false if already exists, throw exception on error</returns>
public bool PutMessage(string queueName, CloudQueueMessage message)
{
try
{
var queue = queueContext.QueueClient.GetQueueReference(queueName);
queue.AddMessage(message);
return true;
}
catch (StorageClientException ex)
{
if ((int)ex.StatusCode == 404) return false;
throw;
}
}
/// <summary>
/// Serializes a e-mail to Json
/// </summary>
/// <param name="from">Sender e-mail address</param>
/// <param name="to">Recipient e-mail address</param>
/// <param name="subject">E-mail subject text</param>
/// <param name="body">E-mail body text</param>
/// <returns>Json</returns>
string SerializeEmail(string from, string to, string subject, string body)
{
var email = new EmailEntity()
{
From = from,
To = to,
Subject = subject,
Body = body
};
var stream = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(EmailEntity));
serializer.WriteObject(stream, email);
var serializedEmail = Encoding.Default.GetString(stream.ToArray());
stream.Close();
return serializedEmail;
}
/// <summary>
/// Puts a e-mail on the Azure queue to be sent
/// </summary>
/// <param name="from">Sender e-mail address</param>
/// <param name="to">Recipient e-mail address</param>
/// <param name="subject">E-mail subject text</param>
/// <param name="body">E-mail body text</param>
/// <returns>Return true on success, false if already exists, throw exception on error</returns>
public bool SendEmail(string from, string to, string subject, string body)
{
var serializedEmail = SerializeEmail(from, to, subject, body);
var message = new CloudQueueMessage(serializedEmail);
return PutMessage(AzureQueueContext.EmailQueueName, message);
}
/// <summary>
/// Retrieve the next message from a queue
/// </summary>
/// <param name="queueName">Name of queue</param>
/// <param name="message">Message</param>
/// <returns>Return true on success (message available), false if no message or no queue, throw exception on error</returns>
bool GetMessage(string queueName, out CloudQueueMessage message)
{
message = null;
try
{
var queue = GetCloudQueueClient().GetQueueReference(queueName);
message = queue.GetMessage();
return message != null;
}
catch (StorageClientException ex)
{
if ((int)ex.StatusCode == 404) return false;
throw;
}
}
/// <summary>
/// Deserializes a e-mail message
/// </summary>
/// <param name="message">Message serialized in the Json inerchange format</param>
/// <returns>Deserialized e-mail as a EmailEntity object</returns>
EmailEntity DeserializeEmail(CloudQueueMessage message)
{
var stream = new MemoryStream(Encoding.Default.GetBytes(message.AsString));
var ser = new DataContractJsonSerializer(typeof(EmailEntity));
var email = (EmailEntity)ser.ReadObject(stream);
stream.Close();
return email;
}
/// <summary>
/// Retrieve the next message from a queue
/// </summary>
/// <param name="email">E-mail</param>
/// <returns>Return true on success (message available), false if no message or no queue, throw exception on error</returns>
public bool GetEmail(out EmailEntity email, out CloudQueueMessage message)
{
var result = GetMessage(AzureQueueContext.EmailQueueName, out message);
email = result ? DeserializeEmail(message) : null;
return result;
}
答案 2 :(得分:0)
我之前通过创建一个完全独立的WebJob来解决这个问题,该WebJob读取XML,拉出JSON,并将JSON值重新排入存储队列(解决方案:https://github.com/Stonefinch/AzureIntro/tree/master/src/AzureIntro.WebJobs.AzureScheduler)
但是,我最近发现使用 Azure Functions 排队邮件提供了一个不错的解决方法。更多信息:http://aaron-hoffman.blogspot.com/2017/01/replace-azure-scheduler-with-azure.html