Azure Function (using DI) cannot remove "/api" route prefix

Viewed 1419

So I'm aware of these two questions that seem to be asking the same thing:

How to remove the word ‘api’ from Azure functions url

How to change the base "/api" path on Azure Functions (v2)?

However, I can still not get rid of the "api" prefix in my route.

My host.json looks like:

{
  "version": "2.0",
  "extensions": {
    "http": {
      "routePrefix": ""
    }
  }
}

And on my HttpTrigger I'm setting my custom route:

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "myapp")] HttpRequest request,

However, when I run the app locally the end point is coming up as:

[POST] http://localhost:7071/api/myapp

If I change my host.json to:

{
  "version": "2.0",
  "extensions": {
    "http": {
      "routePrefix": "something"
    }
  }
}

My app is now running on:

[POST] http://localhost:7071/something/myapp

So it appears that giving an empty string "" is just not working. Any ideas? (I've done all the usual stuff: clean solution, delete bin/obj folder etc.)

FYI from my function app I'm using:

<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />

EDIT:

I'm also referencing these packages from the function app (though I don't see how this would cause this problem):

<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureKeyVault" Version="3.1.1" />

EDIT 2

I've narrowed down the problem to this code that is called in Startup.cs:

IConfiguration configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();

IConfiguration combinedConfig = new ConfigurationBuilder()
    .AddConfiguration(configuration)
    .AddAzureKeyVault(kvEndpoint, kvClient, new DefaultKeyVaultSecretManager());
    .Build();

builder.Services.AddSingleton(combinedConfig);
// <-- this line causes the prefix "" to revert to "/api"

It essentially is adding key vault as a configuration provider to the stack of providers all ready there. (Note it doesnt matter what .Add methods I call on configuration builder, its the registration that is causing a problem). Is there another way to write this maybe?

2 Answers

So the mistake I seem to have made was very small. In the following code:

IConfiguration configuration = builder.Services.BuildServiceProvider().GetService<IConfiguration>();

IConfiguration combinedConfig = new ConfigurationBuilder()
    .AddConfiguration(configuration)
    .AddAzureKeyVault(kvEndpoint, kvClient, new DefaultKeyVaultSecretManager());
    .Build();

builder.Services.AddSingleton(combinedConfig);

ConfigurationBuild.Build() actually returns a IConfigurationRoot, NOT a IConfiguration (IConfigurationRoot is a superset of IConfiguration). So when registering it I was loosing something (probably config provider information).

Simply changing:

IConfiguration combinedConfig

to

IConfigurationRoot combinedConfig

fixes the problem (or you can use var, which I probably should have!).

Though this fixes the problem I am still a little confused why before changing the routePrefix in host.json to some non-empty string works but setting it to empty string does not. Would have thought simply having the setting in the host.json at all would just apply the value and not having it there would mean reverting to the default "api".

I tried, and it's working!

I used VS2019, Created Azure function default project with HTTP trigger and remove route prefix from host.json

enter image description here

Proj file

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.31" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

After updating nuget packages with latest version, it's working.

enter image description here

Proj file

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>v2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Core" Version="3.0.16" />
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.2" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.7" />
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>
Related