You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C#以编程方式查找并调用指定区域的Azure Function

C# 基于MSI认证按指定区域调用Azure Function实现方案

前置准备

  • 提前维护区域参数与对应Azure Function部署实例的根地址映射,例如useast2对应https://<your-func-app-name>-useast2.azurewebsites.net,映射关系建议存在环境变量、应用配置服务或配置文件中,禁止硬编码在业务逻辑内。
  • 为调用方配置的托管标识(系统分配/用户分配MSI)授予所有跨区域部署Function实例的调用权限:若Function开启了AAD身份验证,需将MSI对应的服务主体添加到每个Function实例的授权列表中,授予接口调用权限,避免鉴权失败。
  • 项目引入必需的NuGet包:Azure.Identity(用于获取MSI令牌)、System.Text.Json(用于请求序列化,可根据项目习惯替换为其他序列化库)。

核心实现代码

首先维护区域-端点映射,生产环境请替换为从配置中心读取:

// 示例为硬编码映射,生产环境从配置加载
private static readonly IReadOnlyDictionary<string, string> RegionEndpointMapping = new Dictionary<string, string>
{
    ["useast2"] = "https://your-func-useast2.azurewebsites.net",
    ["westeurope"] = "https://your-func-westeurope.azurewebsites.net",
    ["chinaeast2"] = "https://your-func-chinaeast2.chinacloudsites.cn"
    // 按实际部署补充所有区域对应地址
};

封装区域调用方法:

// 生产环境建议用IHttpClientFactory创建HttpClient实例做复用
private static readonly HttpClient _httpClient = new HttpClient();

/// <summary>
/// 按指定区域调用Azure Function
/// </summary>
/// <param name="region">区域参数,例如useast2</param>
/// <param name="apiRoute">Function接口路由,例如/api/OrderProcess</param>
/// <param name="payload">请求参数</param>
/// <param name="userAssignedMsiClientId">用户分配MSI的客户端ID,用系统分配MSI可传null</param>
/// <param name="ct">取消令牌</param>
public async Task<string> CallFunctionByRegionAsync(string region, string apiRoute, object payload, string? userAssignedMsiClientId = null, CancellationToken ct = default)
{
    // 校验区域参数,解析目标请求地址
    if (!RegionEndpointMapping.TryGetValue(region.ToLowerInvariant(), out var funcBaseAddress))
    {
        throw new ArgumentOutOfRangeException(nameof(region), $"未找到区域{region}对应的Function部署实例");
    }
    var requestUri = new Uri(new Uri(funcBaseAddress), apiRoute.TrimStart('/'));

    // 获取MSI访问令牌
    var credentialOptions = new DefaultAzureCredentialOptions();
    if (!string.IsNullOrEmpty(userAssignedMsiClientId))
    {
        credentialOptions.ManagedIdentityClientId = userAssignedMsiClientId;
    }
    // 若涉及Azure中国、美国政府等独立云环境,此处需配置对应AuthorityHost
    var credential = new DefaultAzureCredential(credentialOptions);
    // 请求令牌的scope固定格式为 {Function根地址}/.default
    var tokenResult = await credential.GetTokenAsync(new TokenRequestContext(new[] { $"{funcBaseAddress}/.default" }), ct);

    // 构造请求发送
    using var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
    request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", tokenResult.Token);
    request.Content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");

    using var response = await _httpClient.SendAsync(request, ct);
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync(ct);
}

关键注意事项

  • DefaultAzureCredential会自动适配运行环境:本地调试时会自动读取Visual Studio、Azure CLI、VS Code的登录凭据获取令牌,部署到Azure服务(VM、App Service、AKS等)后会自动使用MSI获取令牌,不需要额外写环境判断逻辑。
  • 若Function部署在Azure私有网络(VNet)内,需要确保调用方所在网络能通过私有链路访问到对应区域Function的私有端点,否则会出现网络不通的问题。
  • Azure.Identity内置了令牌缓存和自动刷新逻辑,不需要手动实现令牌过期处理,不要每次调用都重复创建DefaultAzureCredential实例,避免重复请求令牌接口产生限流。
  • 如果使用Function部署槽位做预发布验证,只需要在区域映射表中补充槽位对应的完整地址(例如https://your-func-useast2-staging.azurewebsites.net),其余逻辑无需修改。

内容的提问来源于stack exchange,提问作者Aarthi Vishwanathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:06:27