如何让一些代码仅在Azure函数首次运行时运行?

时间:2019-05-02 00:47:11

标签: azure botframework azure-functions dotnet-httpclient

我正在编写azure函数以从令牌服务请求令牌。具体来说,是聊天机器人的网络聊天令牌,为此,我需要在请求中附加一个承载令牌,并且所有请求都只有一个httpClient。

我只想运行一次以下行: httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);。第一次调用该函数,否则会出现一条错误消息,说明授权标头已经存在。

我当前的解决方法是使用另一个静态布尔值,该值在首次运行后会进行检查并在之后进行更新。

这是下面的azure函数的代码。

#r "Newtonsoft.Json"

using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;


private static string secret = "";

private static HttpClient httpClient = new HttpClient();
private static bool runOnce = true;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    if (runOnce){
        httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + secret);
        runOnce = false;
    }

    // Token request
    var response = await httpClient.GetAsync("https://webchat.botframework.com/api/tokens");
    var contents = await response.Content.ReadAsStringAsync();

    var obj = new ReturnObject();
    obj.Token = contents;

    var json = JsonConvert.SerializeObject(obj);

    return new OkObjectResult(json);
}

public class ReturnObject
{
    public string Token {get; set;}
}

现在似乎可以正常工作,但是应该有一种更合适的方法来做到这一点。 谢谢!

2 个答案:

答案 0 :(得分:4)

您可以使用Static Constructor,它“用于初始化任何静态数据,或执行仅需要执行一次的特定操作。在创建第一个实例或任何静态对象之前会自动调用它。成员被引用。”

例如:

class Globals
{
    public readonly static HttpClient httpClient;
    public readonly static string secret;
    static Globals()
    {
        httpClient = new HttpClient();
        secret = "";
        httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + secret);
    }
}

请记住,功能应用程序可能同时运行多个实例。静态构造函数将在每个应用程序实例中被调用一次,并且在您的函数应用程序重新启动时将被重复。

答案 1 :(得分:1)

V2可能还有一个选择

[assembly: WebJobsStartup(typeof(InjectWebJobsStartup))]

namespace Startup
{
    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            // Do init here
        }
    }
}

但是由于您需要HttpClient,所以也许最好使用静态类。