2017-04-12 48 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