2017-04-12 40 views
2

所以第一關,我用下面的博客文章來幫助我,我的CSX Azure的功能轉換爲預編譯類庫 - https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/?utm_source=Direct預編譯Azure的功能上HttpClientExtensions.SetBearerToken使用拋出錯誤,CSX不

我已經達到了我認爲應該起作用的地步,但作爲一個預編譯函數,它在SetBearerToken(它在System.Net.Http.HttpClientExtensions中)上拋出了'Method Not Found'異常,但它沒有任何在CSX版本中找到此方法時遇到問題。下面是完整的錯誤:

Exception while executing function: Functions.notifications-queue-trigger Microsoft.Azure.WebJobs.Host.FunctionInvocationException : Exception while executing function: Functions.notifications-queue-trigger ---> System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. ---> System.MissingMethodException : Method not found: 'Void System.Net.Http.HttpClientExtensions.SetBearerToken(System.Net.Http.HttpClient, System.String)'.

的代碼是預編譯功能&的CSX腳本(比要求的差異明顯等)之間幾乎identitcal。

我在這裏錯過了什麼?爲什麼它在預編譯版本的System.Net.Http.HttpClientExtensions中爲SetBearerToken拋出一個'Method Not Found'異常,但它在作爲CSX腳本寫入時沒有問題?任何幫助讚賞。

這是我作爲一個CSX腳本函數,這個工程:

#r "IdentityModel.dll" 
#r "Sorbet.DataTransferObjects.dll" 
#r "Newtonsoft.Json" 

using System; 
using System.Text; 
using System.Threading.Tasks; 
using System.Net.Http; 

using IdentityModel.Client; 
using Newtonsoft.Json; 
using Sorbet.DataTransferObjects; 

public static void Run(NotificationDto myQueueItem, TraceWriter log) 
{ 
    log.Info($"C# ServiceBus queue trigger function processed message"); 
    TokenResponse idToken; 
    using (var tokenClient = new TokenClient("https://myidserver", "myclientid", "myclientsecret")) 
    { 
     var response = tokenClient.RequestClientCredentialsAsync("myscope"); 
     idToken = response.Result; 
     log.Info($"Access token retrieved : {idToken.AccessToken}"); 
    } 

    using (var apiClient = new HttpClient()) 
    { 
     var apiUrl = "https://myapiurl/"; 
     var endpoint = "myendpoint"; 
     string data = JsonConvert.SerializeObject(myQueueItem); 
     log.Info($"Hitting API..."); 

     apiClient.SetBearerToken(idToken.AccessToken); 
     var response = apiClient.PostAsync($"{apiUrl}{endpoint}", new StringContent(data, Encoding.UTF8, "application/json")).Result; 
    } 
} 

這是我作爲一個C#類的功能,這將引發上述錯誤的SetBearerToken電話:

using System; 
using System.Text; 
using System.Threading.Tasks; 
using System.Net.Http; 

using IdentityModel.Client; 
using Microsoft.Azure.WebJobs.Host; 
using Newtonsoft.Json; 
using Sorbet.DataTransferObjects; 

namespace FunctionsClassLibTest 
{ 
    public class NotificationQueueTrigger 
    { 
     public static void Run(NotificationDto myQueueItem, TraceWriter log) 
     { 
      log.Info($"C# ServiceBus queue trigger function processed message"); 
      TokenResponse idToken; 
      using (var tokenClient = new TokenClient("https://myidserver", "myclientid", "myclientsecret")) 
      { 
       var response = tokenClient.RequestClientCredentialsAsync("myscope"); 
       idToken = response.Result; 
       log.Info($"Access token retrieved : {idToken.AccessToken}"); 
      } 

      using (var apiClient = new HttpClient()) 
      { 
       var apiUrl = "https://myapiurl"; 
       var endpoint = "myendpoint"; 
       string data = JsonConvert.SerializeObject(myQueueItem); 
       log.Info($"Hitting API..."); 

       apiClient.SetBearerToken(idToken.AccessToken); 
       var response = apiClient.PostAsync($"{apiUrl}{endpoint}", new StringContent(data, Encoding.UTF8, "application/json")).Result; 
      } 
     } 
    } 
} 

而且這裏是我的預編譯功能function.json文件(CSX之一幾乎相同,但它只有綁定部分)

{ 
    "scriptFile": "..\\bin\\FunctionsClassLibTest.dll", 
    "entryPoint": "FunctionsClassLibTest.NotificationQueueTrigger.Run", 
    "bindings": [ 
    { 
     "name": "myQueueItem", 
     "type": "serviceBusTrigger", 
     "direction": "in", 
     "queueName": "notifications", 
     "connection": "dev-bus", 
     "accessRights": "manage" 
    } 
    ], 
    "disabled": false 
} 
+0

看起來像'IdentityModel.dll'沒有正確加載。你如何參考它?在附註中,儘量將您的代碼示例最小化爲重現問題所需的最小量。 – Mikhail

+0

謝謝米哈伊爾。我這次只發布了完整的代碼,因爲它看起來像是一個奇怪的問題,其中一個可能會變得很小! IdentityModel是我的第一個想法,但它似乎通過IdentityModel的東西確定,這是第一次使用聲明的東西,我的ID服務器,並獲得我的令牌。它在第二個使用語句中調用SetBearerToken時下降了,這是System.Net.Http.HttpClientExtensions中的HttpClient的擴展方法,具有MissingMethodException – yellowbrickcode

+0

啊,是的,我的不好 - 它確實在抱怨HttpClientExtensions。你明白爲什麼我要求一個更小的例子;)你仍然處於嘗試從函數中刪除某些部分的最佳位置(例如IdentityServer),並查看是否改變了結果 - 並相應地調整你的問題。 – Mikhail

回答

1

好的,所以我想出了一個解決方案。問題出在我認爲它可能在一開始就是在IdentityModel庫中。我被命名空間拋出,錯誤正在被拋出,這讓我在幾個小時的時間裏瘋狂追趕。實際上,在IdentityModel庫中定義了HttpClient的擴展。

知道到底哪裏出了問題實際上是,我看着擴展和剛剛更換與代碼行apiClient.SetBearerToken("mytoken");在擴展方法apiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "mytoken);被使用,這是現在在我的預編譯功能工作。

這並不回答爲什麼它在CSX中工作,而不是預編譯功能。如果任何人有任何想法,爲什麼這可能是我真的有興趣知道!我知道導入IdentityModel庫並不是問題,因爲我使用它從我的ID服務器獲取令牌,並且工作正常,因此它必須是特定於擴展方法的內容。有問題的擴展方法可以在這裏看到 - https://github.com/IdentityModel/IdentityModel/blob/master/source/IdentityModel.Shared/Client/HttpClientExtensions.cs

+0

從預編譯的函數中查看您引用的System.Net.Http版本會很有趣。我們可能正在處理某些類型不匹配,導致無法在運行時綁定到這些方法。 –

+0

下面是我的'packages.config'中的元素。這只是我創建項目時安裝的版本'' – yellowbrickcode

+0

對不起,我剛剛注意到System.Net .Http軟件包作爲IdentityModel軟件包的依賴項安裝,因此它不在項目創建中。 – yellowbrickcode