Alors d'abord, j'utilise le billet de blog pour me aider à convertir ma CSX Azure fonction d'une bibliothèque de classes précompilés - https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/?utm_source=Directprécompilés Azure Fonction lancer erreur sur HttpClientExtensions.SetBearerToken utilisation, CSX ne
I J'en suis au point où je pense que ça devrait fonctionner, mais en tant que fonction précompilée, il lance une exception 'Méthode introuvable' sur SetBearerToken (qui est dans System.Net.Http.HttpClientExtensions) mais il n'a pas de problème de trouver cette méthode dans la version CSX. Voici la pleine erreur:
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)'.
Le code est à peu près identitcal entre la fonction précompilé & le script CSX (autre que les différences nécessaires évidemment).
Qu'est-ce qui me manque ici? Pourquoi lance-t-il une exception 'Méthode non trouvée' pour SetBearerToken dans System.Net.Http.HttpClientExtensions dans la version précompilée alors qu'elle n'a pas de problème lorsqu'elle est écrite en tant que script CSX? Toute aide appréciée.
Voici ma fonction en tant que script CSX, cela fonctionne:
#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;
}
}
Voici ma fonction en tant que classe C#, cela jette l'erreur ci-dessus sur l'appel 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;
}
}
}
}
Et voici mon fichier function.json
pour ma fonction précompilée (la CSX est presque la même mais elle n'a que la section des liaisons)
{
"scriptFile": "..\\bin\\FunctionsClassLibTest.dll",
"entryPoint": "FunctionsClassLibTest.NotificationQueueTrigger.Run",
"bindings": [
{
"name": "myQueueItem",
"type": "serviceBusTrigger",
"direction": "in",
"queueName": "notifications",
"connection": "dev-bus",
"accessRights": "manage"
}
],
"disabled": false
}
Apparemment, 'IdentityModel.dll' ne se charge pas correctement. Comment faites-vous référence? D'un côté, essayez de minimiser votre échantillon de code au minimum nécessaire pour reproduire le problème. – Mikhail
Merci Mikhail. Je n'ai posté que du code complet cette fois-ci parce qu'il me semble que c'est un problème si étrange, un de ceux qui pourraient être à quelque chose de minuscule! IdentityModel a été ma première pensée aussi, mais il semble que je passe les choses d'IdentityModel d'accord, c'est le truc dans la première instruction using qui va à mon serveur d'identification et obtient mon jeton. Il tombe sur l'appel à SetBearerToken dans la deuxième instruction using qui est une méthode d'extension pour HttpClient dans System.Net.Http.HttpClientExtensions avec une exception MissingMethod – yellowbrickcode
Ah, oui, mon mauvais - il se plaint de 'HttpClientExtensions' en effet.Vous voyez pourquoi j'ai demandé un plus petit exemple;) Vous êtes toujours dans la meilleure position pour essayer de supprimer certaines parties de la fonction (par exemple IdentityServer) et voir si cela change le résultat ou non - et ajuster votre question en conséquence. – Mikhail