I have been working on upgrading one of our Azure Functions implementations to .net 5. I have battled may demons already but just as I though I had sorted out all the config and dependency injection changes, it throws a curve ball at me. After host.RunAsync
in Main
, I get the following exception and I am at a bit of a loss as to the culprit. Has anyone run into and fixed this one?
System.UriFormatException
HResult=0x80131537
Message=Invalid URI: The hostname could not be parsed.
Source=System.Private.Uri
StackTrace:
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at Grpc.Net.Client.GrpcChannel.ForAddress(String address, GrpcChannelOptions channelOptions)
at Microsoft.Extensions.DependencyInjection.GrpcServiceCollectionExtensions.<>c.<AddGrpc>b__1_1(IServiceProvider p) in D:\a\1\s\src\DotNetWorker.Grpc\GrpcServiceCollectionExtensions.cs:line 58
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__9.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at MySoftware.FunctionApp.Program.<Main>(String[] args)
This exception was originally thrown at this call stack:
[External Code]
My Program.cs main looks like:
using Microsoft.Extensions.Hosting;
using System.Threading.Tasks;
namespace FunctionApp1
{
/// <summary>
/// Entry
/// </summary>
public class Program
{
static async Task Main(string[] args)
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.Build();
await host.RunAsync();
}
}
}
And my Function
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.IO;
using System.Threading.Tasks;
namespace FunctionApp1
{
/// <summary>
///
/// </summary>
public static class Function1
{
/// <summary>
///
/// </summary>
/// <param name="req"></param>
/// <param name="ctx"></param>
/// <returns></returns>
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req, FunctionContext ctx)
{
ctx.GetLogger("out").LogInformation("C# HTTP trigger function processed a request.");
string name = req.ReadAsString();
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
When I use func host start
I also get the error "No job functions found. Try making your job classes and methods public."
[2021-04-09T07:37:04.953Z] FUNCTIONS_WORKER_RUNTIME set to dotnet-isolated. Skipping WorkerConfig for language:python
[2021-04-09T07:37:04.954Z] Reading functions metadata
[2021-04-09T07:37:04.955Z] 0 functions found
[2021-04-09T07:37:04.962Z] 0 functions loaded
[2021-04-09T07:37:04.969Z] Generating 0 job function(s)
[2021-04-09T07:37:04.978Z] No job functions found. Try making your job classes and methods public. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
[2021-04-09T07:37:04.983Z] Initializing function HTTP routes
[2021-04-09T07:37:04.985Z] No HTTP routes mapped
[2021-04-09T07:37:04.986Z]
[2021-04-09T07:37:04.994Z] Host initialized (53ms)
[2021-04-09T07:37:04.997Z] Host started (63ms)
[2021-04-09T07:37:04.998Z] Job host started
For detailed output, run func with --verbose flag.
As of March 2021, Microsoft announced that Azure Functions are supported running on . NET 5.
Use the following procedure to view and update the runtime version currently used by a function app. In the Azure portal, browse to your function app. Under Settings, choose Configuration. In the Function runtime settings tab, locate the Runtime version.
NET to version 6. You can do that by updating to the new shiny Visual Studio 2022 with built-in SDK or downloading it from here: . NET 6.0 SDK. In Visual Studio 2022, Azure Functions Core Tools, necessary for developing Azure Functions, are available by adding the Azure Cloud Tool in the installation process of VS.
NET Framework and only supports development in the Azure portal, Azure Stack Hub portal, or locally on Windows computers. This version is in maintenance mode, with enhancements provided only in later versions. Beginning on December 3, 2022, function apps running on versions 2.
In order to update it to use .NET 5 we need to: Update the target framework to net5.0 Add the OutputType of Exe Upgrade Microsoft.Extensions.DependencyInjection to 5.x Microsoft.Azure.Functions.Extensions Microsoft.Azure.WebJobs.Extensions.EventGrid
You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in local.settings.json. If you are using version 5.x or higher of the extension, instead of a connection string, you can provide a reference to a configuration section which defines the connection.
For example, if you set connection to "MyServiceBus", the Functions runtime looks for an app setting that is named "AzureWebJobsMyServiceBus". If you leave connection empty, the Functions runtime uses the default Service Bus connection string in the app setting that is named "AzureWebJobsServiceBus".
You can run 'func azure functionapp fetch-app-settings ' or specify a connection string in local.settings.json. If you are using version 5.x or higher of the extension, instead of a connection string, you can provide a reference to a configuration section which defines the connection. See Connections.
Currently, .net 5 azure function
is not supported very well with tools like visual studio. You can run your function by using this command func host start
in Azure Functions Core Tools.
There is also a similar issue in github, you can refer to the issue for more details.
It cost me half a day to figure this out, but you need to replace [FunctionName("Function1")]
with [Function("Function1")]
. Apparently this is something that changed in Azure Functions 3, but as far as I know it isn't mentioned anywhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With