Precompiled Azure Function throwing error on HttpClientExtensions.SetBearerToken use, CSX doesn't

こ雲淡風輕ζ 提交于 2019-12-10 23:04:32

问题


So first off, I'm using the following blog post to help me convert my CSX Azure Function to a precompiled class library - https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/?utm_source=Direct

I've got it to the point where I think it should be working, but as a precompiled function it throws a 'Method Not Found' exception on SetBearerToken (which is in System.Net.Http.HttpClientExtensions) but it doesn't have any problem finding this method in the CSX version. Here's the full error:

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)'.

The code is pretty much identitcal between the precompiled function & the CSX script (other than the required differences obviously).

What am I missing here? Why is it throwing a 'Method Not Found' exception for SetBearerToken in System.Net.Http.HttpClientExtensions in the precompiled version when it has no problems when writted as a CSX script? Any help appreciated.

Here is my function as a CSX script, this works:

#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;
    }
}

Here is my function as a C# class, this throws the above error on the SetBearerToken call:

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;
            }
        }
    }
}

And here is my function.json file for my precompiled function (the CSX one is almost the same but it only has the bindings section)

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

回答1:


Ok, so I've figured out a solution for this. The problem was where I thought it might have been right at the start, in the IdentityModel library. I was thrown by the namespace that the error was being thrown from which sent me off on a wild goose chase for a couple of hours. In fact, the extensions for HttpClient were being defined in the IdentityModel library.

Knowing exactly where the problem actually was, I looked at the extensions and just replaced the line apiClient.SetBearerToken("myBearerToken"); with the code being used in that extension method apiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "myBearerToken"); and this is now working in my precompiled function.

This doesn't answer the question of why it works in the CSX and not the precompiled function though. If anyone has any ideas on why that might be I'd be really interested to know! I know it's not a problem with the import of the IdentityModel library as I use that to get the token from my ID server and that works fine so it must be something specific to the extension methods. The extension methods in question can be seen here - https://github.com/IdentityModel/IdentityModel/blob/master/source/IdentityModel.Shared/Client/HttpClientExtensions.cs



来源:https://stackoverflow.com/questions/43367113/precompiled-azure-function-throwing-error-on-httpclientextensions-setbearertoken

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!