#.net-core #azure-functions
Вопрос:
Как и многие, я использую HttpClient в некоторых своих функциях Azure (v3.x). Проблема в том, что узел функций Azure использует HttpClient в качестве одного элемента. Это означает, что если я установлю заголовки в одной функции, они будут установлены для всех функций. Я хочу иметь разные заголовки (например, заголовки авторизации) в разных функциях. Является ли единственным способом добиться этого создание различных функциональных приложений для каждого набора заголовков, которые мне нужны?
Комментарии:
1. Вы должны иметь возможность использовать HttpClientFactory и настраивать именованные или типизированные клиенты.
Ответ №1:
Обычно вы не используете «глобальные HttpClient
« DefaultRequestHeaders
. Вы хотели бы создать HttpRequestMessage
и использовать SendAsync
. Это дает этому сеансу уникальный словарь заголовков, который отделен от всех других запросов.
HttpClient
они DefaultRequestHeaders
не являются потокобезопасными. Поэтому, если вы измените их в середине другого запроса, произойдет сбой.
Что вам следует сделать, так это внедрить HttpClientFactory
, а затем создать из этого клиентов. Продолжайте использовать шаблон HttpRequestMessage
/ SendAsync
(или используйте прямой GetAsync
PostAsync
, и т. Д.), Избегая DefaultRequestHeaders
при этом (если вы используете заводской CreateClient()
метод).
Если вы используете фабрику, вы можете использовать, DefaultRequestHeaders
если создадите именованный или типизированный HttpClient
объект с фабрики. Вероятно, вы захотите сделать это для своего конкретного случая использования, о котором вы упомянули в своем вопросе.
Пример
- Запустите новый проект функций Azure.
- Добавление
Microsoft.Azure.Functions.Extensions
иMicrosoft.Extensions.Http
пакеты через NuGet. - Добавьте новый класс, назовите его
Startup.cs
. Сделай так, чтобы это выглядело так:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http.Headers;
[assembly: FunctionsStartup(typeof(MyAzureFunction.Startup))]
namespace MyAzureFunction
{
public sealed class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient("MyAuthorizedClient", client =>
{
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "<token>");
});
}
}
}
- По умолчанию класс функции и сама функция являются
static
. Обязательно удалитеstatic
ключевое слово. Затем добавьте конструктор. Мы введем фабрику через конструктор:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace MyAzureFunction
{
public sealed class Function1
{
private readonly IHttpClientFactory _httpClientFactory;
public Function1(IHttpClientFactory httpContextFactory)
{
_httpClientFactory = httpContextFactory;
}
[FunctionName("Function1")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
//
// make a request on the authorized client
var authorizedClient = _httpClientFactory.CreateClient("MyAuthorizedClient");
using (var response = await authorizedClient
.GetAsync(new Uri("https://www.example.com")))
{
var objRecved = await response.Content.ReadAsAsync<object>();
return new OkObjectResult(new { data = objRecved });
}
//
// make a request on the non-authorized client using it's own header collection
var nonAuthorizedClient = _httpClientFactory.CreateClient();
using (var request = new HttpRequestMessage(
HttpMethod.Get, new Uri("https://www.example.com")))
{
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", "<token>");
using(var response = await nonAuthorizedClient.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var objRecved = await response.Content.ReadAsAsync<object>();
return new OkObjectResult(new { data = objRecved });
}
}
}
}
}
Комментарии:
1. Я получаю следующее, когда пытаюсь запустить приложение-функцию локально
Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'httpClientFactory' to type IHttpClientFactory. Make sure the parameter Type is supported by the binding
.2. @HisDivineShadow — упс.. Извини за это. Я обновил код.