azure-functions-host: routePrefix ignored when using ConfigurationBuilder
In WebJobsStartup
, if merging original configuration with custom configuration, the routePrefix
defined in host.json
is ignored and all HttpTrigger
functions use “api” as routePrefix
I have not deployed this to any Azure resource yet, and I’m only running locally, so please bear with the lack of investigative information
Investigative information
Please provide the following:
- Timestamp: 2019-04-30
- Function App version: 2.0
- Function App name: N/A
- Function name(s) (as appropriate): N/A
- Invocation ID: N/A
- Region: N/A
Repro steps
Use the following code in a WebJobsStartup to add support for custom config-files
[assembly: WebJobsStartup(typeof(Startup))]
namespace MyFuncApp {
public class Startup : IWebJobsStartup {
public void Configure(IWebJobsBuilder builder)
{
//Get the current config and merge it into a new ConfigurationBuilder to keep the old settings
ConfigurationBuilder configBuilder = new ConfigurationBuilder();
var descriptor = builder.Services.FirstOrDefault(d => d.ServiceType == typeof(IConfiguration));
if (descriptor?.ImplementationInstance is IConfigurationRoot configuration)
{
configBuilder.AddConfiguration(configuration);
}
IConfigurationRoot config = configBuilder.Build();
//replace the existing config with the new one
builder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), config));
}
}
This should use the existing configurations inside a new ConfigurationBuilder
. I could now add .AddJsonFile(...)
if I wanted to, however for this example I’ve just created a new ConfigurationBuilder
, copied the existing config into this builder, created a new config object from this builder, and replace the old config object with the new one, so there are no custom configurations to override anything.
If I debug I can see that the config
variable contains a (private) ChainedConfigurationProvider
that contains all the default configurations, including the HostJsonFileConfigurationProvider
that has routePrefix: ""
.
When starting the Function app locally I can see that the routePrefix
is now ignored, and all my functions have “api” at the start of their route, even though my host.json has a blank value. Here’s my host.json:
{
"version": "2.0",
"extensions": {
"http": {
"routePrefix": ""
}
}
}
It all boils down to this line of code:
builder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), config));
If I remove this the routePrefix
is blank (as stated in the host.json file). If this line is used the routePrefix
is “api”.
It would therefore seem that there might be a bug in the routePrefix
resolver that fails to read the prefix from host.json
whenever a custom IConfiguration
is used, even if this configuration should have merged in the settings from the old configuration.
Expected behavior
Configurations should be merged without overwriting routePrefix
functionality
Actual behavior
routePrefix
gets reset to "api"
even if it is ""
in host.json
Known workarounds
N/A
Related information
- Obviously coded in C#
- HttpBindings
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 5
- Comments: 20 (4 by maintainers)
The workaround mentioned by @xperiandri seemed to do the trick for now. I added the the following line to to the Startup.cs:
services.Configure<HttpOptions>(options => options.RoutePrefix = string.Empty);
It is half of 2023…
What I seem to have observed in testing this out is that the value specified in
host.json
using the above approach is obeyed if you use a value other than""
. Example, I set it to"foo"
and my routes were discovered with a routePrefix of/foo
. There seems to be something about empty string specifically.same issue as @nadershamma with a v4 function. Honestly if it’s been 2 years and multiple function app versions, I am not hopefully that MS will take this issue seriously.
the most annoying part is that if I deploy using the
func azure functionapp publish
command, it properly sets the api route from/api
to/api/whatever
but when I deploy in azure devops, it always ignores my host.json file and sets it to/api
. Tremendously frustrating.Has anyone found a way to get the route prefix set through azure devops? Here’s my yaml for doing the deployment to my function app slot.
Woked around with
.Configure<HttpOptions>(fun (options : HttpOptions) -> options.RoutePrefix <- String.Empty; ())
for now. But it is weird@gthvidsten as a workaround you can do the following in the startup:
This works for functions runtime V3, tested both locally and in the cloud.