我正在编写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;}
}
现在似乎可以正常工作,但是应该有一种更合适的方法来做到这一点。 谢谢!
答案 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,所以也许最好使用静态类。