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

Azure Function App部署异常:dotnet-isolated函数未显示

.NET 8 Isolated Azure Function 发布后无法加载函数问题

我正在开发并部署一个基于.NET 8的dotnet-isolated类型Azure Function。通过Visual Studio右键发布到Azure时,函数能正常显示;但使用Jenkins或Azure CLI发布包后,Azure Function App中无法看到该函数,且提示“0 functions found / 0 functions loaded”。期望通过自动化发布流程后,函数能在Azure中正常显示。


启动代码

using Claros.IoT.Azure.Function.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddHttpClient();
        services.AddTransient<ITokenService>(s =>
        {
            var factory = s.GetRequiredService<IHttpClientFactory>();
            var httpClient = factory.CreateClient();
            return new TokenService(httpClient);
        });
        services.AddTransient<IApiManager>(s =>
        {
            var factory = s.GetRequiredService<IHttpClientFactory>();
            var httpClient = factory.CreateClient();
            var tokenService = s.GetService<ITokenService>();
            return new ApiManger(tokenService);
        });
        services.AddTransient<IApiManager, ApiManger>();
        services.AddSingleton<ITokenService, TokenService>();
    })
    .Build();
host.Run();

.csproj 配置文件

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <OutputType>Exe</OutputType>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PublishTrimmed>false</PublishTrimmed>
        <FunctionsWorkerUseHostBuilder>true</FunctionsWorkerUseHostBuilder>
        <GenerateEntryPoint>true</GenerateEntryPoint>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.17.0" OutputItemType="Analyzer" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.1" />
        <PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
    </ItemGroup>
    <ItemGroup>
        <ProjectReference Include="..\Claros.IoT.Azure.Function.Core\Claros.IoT.Azure.Function.Core.csproj" />
    </ItemGroup>
    <ItemGroup>
        <None Update="host.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
        <None Update="local.settings.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <CopyToPublishDirectory>Never</CopyToPublishDirectory>
        </None>
    </ItemGroup>
</Project>

函数实现代码

using Claros.IoT.Azure.Function.Core;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Text.Json;
using System.Threading.Tasks;

namespace Claros.IoT.Azure.IoTHubConnect
{
   public class GetIoTHubDeviceAllocationInfoFunction
   {
       private readonly ILogger _logger;
       private readonly IApiManager _apiManager;

       public GetIoTHubDeviceAllocationInfoFunction(ILogger<GetIoTHubDeviceAllocationInfoFunction> logger, IApiManager apiManager)
       {
           _logger = logger;
           _apiManager = apiManager;
       }

       [Function("GetIoTHubDeviceAllocationInfoFunction")]
       public async Task<HttpResponseData> Run(
           [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestData req,
           FunctionContext executionContext)
       {
           _logger.LogInformation("C# HTTP trigger function processed a request.");
           var query = System.Web.HttpUtility.ParseQueryString(req.Url.Query);
           string deviceId = query["deviceId"];
           string geoLocation = query["geoLocation"];
           if (string.IsNullOrWhiteSpace(deviceId) || string.IsNullOrWhiteSpace(geoLocation))
           {
               var badRequestResponse = req.CreateResponse(HttpStatusCode.BadRequest);
               await badRequestResponse.WriteStringAsync("Please pass a deviceId and geoLocation on the query string.");
               return badRequestResponse;
           }
           var result = await _apiManager.GetIoTHubDeviceAllocationInfoAsync(deviceId, geoLocation);
           var response = req.CreateResponse(HttpStatusCode.OK);
           response.Headers.Add("Content-Type", "application/json");
           string jsonResult = JsonSerializer.Serialize(result, new JsonSerializerOptions
           {
               PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
               WriteIndented = true
           });
           await response.WriteStringAsync(jsonResult);
           return response;
       }
   }
}

launchsettings.json 配置

{
    "profiles": {
       "Claros.IoT.Azure.FunctionApp": {
         "commandName": "Project",
         "commandLineArgs": "--port 7023",
         "launchBrowser": false,
         "environmentVariables": {
           "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
         }
       }
    }
}

Terraform 部署配置

resource "azurerm_windows_function_app" "function_ClarosIoTAzureFunctionApp" {
  name                       = "function-${terraform.workspace}-clarosiotazurefunctionapp"
  location                   = var.location
  resource_group_name        = azurerm_resource_group.fusion.name
  service_plan_id            = azurerm_service_plan.appservice_function.id
  storage_account_name       = azurerm_storage_account.storage.name
  storage_account_access_key = azurerm_storage_account.storage.primary_access_key

  site_config {
    ftps_state = "AllAllowed"
    application_stack {
      dotnet_version = "v8.0"
    }
  }

  app_settings = {
    FUNCTIONS_WORKER_RUNTIME         = "dotnet-isolated"
    FUNCTIONS_WORKER_RUNTIME_VERSION = "~8"
    FUNCTIONS_EXTENSION_VERSION      = "~4"
    WEBSITE_RUN_FROM_PACKAGE         = "1"
    WEBSITE_USE_PLACEHOLDER_DOTNETISOLATED  = "1"
  }

  tags = {
    Region      = var.location
    Createdby   = var.created_by_tag
    Team        = var.team_tag
    Environment = terraform.workspace
    ninetofive  = var.ninetofivetag
  }
}

host.json 配置

{
    "version": "2.0",
    "logging": {
        "applicationInsights": {
            "samplingSettings": {
                "isEnabled": true,
                "excludedTypes": "Request"
            },
            "enableLiveMetricsFilters": true
        }
    }
}

function.metadata 文件

[
  {
    "name": "GetIoTHubDeviceAllocationInfoFunction",
    "scriptFile": "Claros.IoT.Azure.IoTHubConnect.dll",
    "entryPoint": "Claros.IoT.Azure.IoTHubConnect.GetIoTHubDeviceAllocationInfoFunction.Run",
    "language": "dotnet-isolated",
    "properties": {
      "IsCodeless": false
    },
    "bindings": [
      {
        "name": "req",
        "direction": "In",
        "type": "httpTrigger",
        "authLevel": "Function",
        "methods": [
          "get"
        ],
        "properties": {}
      },
      {
        "name": "$return",
        "type": "http",
        "direction": "Out"
      }
    ]
  },
  {
    "name": "HelloTest",
    "scriptFile": "Claros.IoT.Azure.IoTHubConnect.dll",
    "entryPoint": "Claros.IoT.Azure.IoTHubConnect.Functions.HelloTest.Run",
    "language": "dotnet-isolated",
    "properties": {
      "IsCodeless": false
    },
    "bindings": [
      {
        "name": "req",
        "direction": "In",
        "type": "httpTrigger",
        "authLevel": "Function",
        "methods": [
          "get",
          "post"
        ],
        "properties": {}
      },
      {
        "name": "$return",
        "type": "http",
        "direction": "Out"
      }
    ]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:44:51