Как запустить какой-то код только в первый раз, запускается функция Azure? - PullRequest
2 голосов
/ 02 мая 2019

Я пишу функцию 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 ]

4 голосов
/ 02 мая 2019

Вы можете использовать Статический конструктор , который "используется для инициализации любых статических данных или для выполнения определенного действия, которое необходимо выполнить только один раз. Он вызывается автоматически перед созданием первого экземпляра или на любые статические элементы ссылаются. "

например:

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 голос
/ 02 мая 2019

Еще один вариант может быть с V2

[assembly: WebJobsStartup(typeof(InjectWebJobsStartup))]

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

Но поскольку вам нужен HttpClient, возможно, статический класс - лучшая идея.

...