1

总之,我有一个 Azure Web 作业CloudQueue通过 WebJobs SDK 的ProcessQueueMessage机制使用CloudQueueMessage参数类型链接到一个。这给了我一个FunctionInvocationException何时通过QueueTrigger.


细节

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

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

并作为我的对象的预期 JSON 表示形式出现在队列中(来自 Cloud Explorer 中的消息文本预览):

{"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-预览

DNX 4.5.1

背景

Troy Hunt - 网络作业入门

MSDN - 如何... 文章

4

1 回答 1

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);
    }
于 2016-03-03T19:31:24.047 回答