0

總之,我使用CloudQueueMessage參數類型,通過WebJobs SDK的ProcessQueueMessage機制將一個Azure Web作業鏈接到CloudQueue。當通過QueueTrigger觸發時,這給了我一個FunctionInvocationExceptionAzure WebJob ProcessQueueMessage無法讀取CloudQueueMessage


詳細

項被使用AddMessageAsync方法成功添加到CloudQueue

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

並且在隊列中作爲我的對象的預期JSON表示出現(從消息在Cloud Explorer中的文本預覽):

{"EmailAddress":"[email protected]", 
"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 - Web Job primer

MSDN - How to... article

回答

1

改變你的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); 
    } 
+0

thanks @zaid。你的兩個建議都避免了這個錯誤。使用'CloudQueueMessage'可以讓我訪問消息的屬性(例如'InsertionTime')並且應該是有效的。從引用的MSDN鏈接:「除了字符串,該參數可能是一個字節數組,一個CloudQueueMessage對象或您定義的POCO。」 – richaux

+0

@richaux,可以將這些屬性添加到方法參數中。您可以在發送端對CloudQueueMessage進行排隊,但是您可以在接收端獲取有關方法參數的內容和元數據,請參閱上面引用的Azure文檔URL中的「獲取隊列或隊列消息元數據」一節。我會更新我的答案以表明完整性。 –

+0

謝謝你的例子。在[github文檔](https://github.com/Azure/azure-webjobs-sdk-extensions/wiki/Binding-Attributes)中找到了一些進一步的背景。 – richaux