我正在编写一个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;}
}
它现在似乎工作,但应该有一个更合适的方法来做到这一点。谢谢!
您可以使用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);
}
}
请记住,您的功能应用可能会同时运行多个实例。每个应用程序实例将调用一次静态构造函数,并在您的函数应用程序重新启动时重复执行。
还有一个选择可能是V2
[assembly: WebJobsStartup(typeof(InjectWebJobsStartup))]
namespace Startup
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
// Do init here
}
}
}
但是既然你需要HttpClient,那么静态类也许是更好的主意。