Azure WebJob ProcessQueueMessage无法读取CloudQueueMessage

时间:2016-03-03 17:57:43

标签: azure azure-webjobs azure-webjobssdk azure-storage-queues

总之,我使用CloudQueue参数类型,通过WebJobs SDK的ProcessQueueMessage机制将{Azure}作业链接到CloudQueueMessage。这通过FunctionInvocationException触发时为QueueTrigger

详细

使用CloudQueue方法将该项目成功添加到AddMessageAsync

await queue.AddMessageAsync(new CloudQueueMessage(JsonConvert.SerializeObject(myObject)));

在队列中显示为我对象的预期JSON表示(来自Cloud Explorer中的Message Text Preview):

{"EmailAddress":"example@mail.com",
 "Subject":"Test",
 "TemplateId":"00-00-00-00-00",
 "Model":{"PropertyName1":"Test1","PropertyName2":"Test2"}
 }

但是,当触发ProcessQueueMessage方法时:

public static async void ProcessQueueMessage(
    [QueueTrigger(queueName)] CloudQueueMessage message, TextWriter log)

...我得到了FunctionInvocationException

Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.ProcessQueueMessage ---> System.InvalidOperationException: Exception binding parameter 'message' ---> System.ArgumentNullException: String reference not set to an instance of a String.
 Parameter name: s
 at System.Text.Encoding.GetBytes(String s)
 at Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage.get_AsBytes() in c:\Program Files (x86)\Jenkins\workspace\release_dotnet_master\Lib\Common\Queue\CloudQueueMessage.Common.cs:line 146
 at Microsoft.Azure.WebJobs.Host.PropertyHelper.CallPropertyGetter[TDeclaringType,TValue](Func`2 getter, Object this)
 at Microsoft.Azure.WebJobs.Host.PropertyHelper.GetValue(Object instance)
 at Microsoft.Azure.WebJobs.Host.Bindings.BindingDataProvider.GetBindingData(Object value)
 at Microsoft.Azure.WebJobs.Host.Queues.Triggers.UserTypeArgumentBindingProvider.UserTypeArgumentBinding.BindAsync(IStorageQueueMessage value, ValueBindingContext context)
 at Microsoft.Azure.WebJobs.Host.Queues.Triggers.QueueTriggerBinding.<BindAsync>d__0.MoveNext()
 --- End of stack trace from previous location where exception was thrown ---
 at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
 at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
 at Microsoft.Azure.WebJobs.Host.Triggers.TriggeredFunctionBinding`1.<BindCoreAsync>d__7.MoveNext()
 --- End of inner exception stack trace ---
 at Microsoft.Azure.WebJobs.Host.Executors.DelayedException.Throw()
 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__31.MoveNext()
 --- End of stack trace from previous location where exception was thrown

这似乎表明message参数未能将JSON读入CloudQueueMessage对象...但它似乎并不表示我控制了它的。

有没有人对为什么会发生这种情况有任何建议?

版本信息

Microsoft.Azure.Webjobs 1.1.1

WindowsAzure.Storage 6.2.2-preview

DNX 4.5.1

背景

Troy Hunt - Web Job primer

MSDN - How to... article

1 个答案:

答案 0 :(得分:2)

更改您的ProcessQueueMessage以接受一个字符串(这是您实际传递给CloudQueuMessage的内容),然后将其取出并反序列化为您的对象:

public static async void ProcessQueueMessage(
    [QueueTrigger(queueName)] string message, TextWriter log)
{
   JsonConvert.DeserializeObject<YourObjectType>(json);
}

或事件更好,如果这是一个POCO对象,那么你所要做的就是改用它:

public static async void ProcessQueueMessage
(
   [QueueTrigger(queueName)] YourObjectType message, 
   TextWriter log
)
{      //....    }

<强>更新 尽管在CloudQueueMessage对象中获取整个内容会很好,但要获取在CloudQueueMessage中发送的属性,您可以将以下参数添加到webjob方法中:

public static async void ProcessQueueMessage(
        [QueueTrigger(queueName)] string logMessage, 
        DateTimeOffset expirationTime,
        DateTimeOffset insertionTime,
        DateTimeOffset nextVisibleTime,
        string id,
        string popReceipt,
        int dequeueCount,
        string queueTrigger,
        CloudStorageAccount cloudStorageAccount,
        TextWriter logger)
    {
        logger.WriteLine(
            "logMessage={0}\n" +
        "expirationTime={1}\ninsertionTime={2}\n" +
            "nextVisibleTime={3}\n" +
            "id={4}\npopReceipt={5}\ndequeueCount={6}\n" +
            "queue endpoint={7} queueTrigger={8}",
            logMessage, expirationTime,
            insertionTime,
            nextVisibleTime, id,
            popReceipt, dequeueCount,
            cloudStorageAccount.QueueEndpoint,
            queueTrigger);
    }