首先,我正在使用以下博文来帮助我将CSX Azure功能转换为预编译的类库 - https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/?utm_source=Direct
我已经达到了我认为它应该工作的程度,但作为预编译函数,它会在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脚本(显然不是所需的差异)。
我在这里缺少什么?为什么在编译为CSX脚本时没有问题时,预编译版本的System.Net.Http.HttpClientExtensions中的SetBearerToken会抛出'Method Not Found'异常?任何帮助赞赏。
这是我作为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 :(得分:1)
好的,所以我已经找到了解决方法。问题是我认为在IdentityModel库中一开始可能是正确的。我被抛出错误的命名空间抛出,这让我在几个小时的疯狂追逐中被发送出去。事实上,HttpClient的扩展正在IdentityModel库中定义。
确切地知道问题的确切位置,我查看了扩展,只是将行apiClient.SetBearerToken("myBearerToken");
替换为该扩展方法apiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "myBearerToken");
中使用的代码,现在这在我的预编译函数中有效。
这并没有回答为什么在CSX中工作的问题,而不是预编译功能。如果有人对我可能真的有兴趣知道为什么有任何想法!我知道导入IdentityModel库不是问题,因为我使用它从我的ID服务器获取令牌,并且工作正常,因此它必须是特定于扩展方法的东西。有问题的扩展方法可以在这里看到 - https://github.com/IdentityModel/IdentityModel/blob/master/source/IdentityModel.Shared/Client/HttpClientExtensions.cs