Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 8, Function Decorators Not Recognized #629

Open
eat-sleep-code opened this issue Nov 28, 2023 · 28 comments
Open

.NET 8, Function Decorators Not Recognized #629

eat-sleep-code opened this issue Nov 28, 2023 · 28 comments

Comments

@eat-sleep-code
Copy link

I am attempting to migrate an Azure Function from .NET 6 to .NET 8 and from in-process to isolated.

I followed the instructions outlined here: https://github.com/Azure/azure-functions-openapi-extension/blob/main/docs/enable-open-api-endpoints-out-of-proc.md

Including updating the the csproj and performing dotnet restore:

image

However, it appears that the decorators are still not recognized?

image

Visual Studio Code indicates: 'OpenApiOperation' is not an attribute class

I have tried dotnet clean, I have tried completely exiting VS Code and restarting.

@remitonning
Copy link

You need to add these usings instead:
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

Best regards,
Remi

@remitonning
Copy link

remitonning commented Nov 30, 2023

But then next problem will come I think. Please confirm if you get the same as me when trying to build your project:

Screenshot 2023-11-30 115846

It error says: "The type or namespace name 'Azure' does not exist in the namespace '[your namespace]' (are you missing an assembly reference?)

@justinyoo
Copy link
Contributor

.NET 8 doesn't support in-process worker as of now. More precisely, .NET 8 "delayed" supports the in-process worker. Therefore, you can't use .NET 8 for your in-process worker.

Please refer to this page:

.NET 8 will at first only be available on the isolated worker model. There will be an initial preview soon, and we remain committed to full support on the isolated worker model the same day that .NET 8 becomes generally available. However, there will not be an in-process equivalent at the same time. That will come in a subsequent release in early 2024, and we will be doing what we can to make it available as soon as possible. So, if you are looking to use .NET 8 right when it comes out, you will have an option with the isolated worker model. But if you wish to continue using the in-process model, there will be a slight delay.

@remitonning
Copy link

.NET 8 doesn't support in-process worker as of now. More precisely, .NET 8 "delayed" supports the in-process worker. Therefore, you can't use .NET 8 for your in-process worker.

Please refer to this page:

.NET 8 will at first only be available on the isolated worker model. There will be an initial preview soon, and we remain committed to full support on the isolated worker model the same day that .NET 8 becomes generally available. However, there will not be an in-process equivalent at the same time. That will come in a subsequent release in early 2024, and we will be doing what we can to make it available as soon as possible. So, if you are looking to use .NET 8 right when it comes out, you will have an option with the isolated worker model. But if you wish to continue using the in-process model, there will be a slight delay.

He is using .NET 8 isolated process:) -> "I am attempting to migrate an Azure Function from .NET 6 to .NET 8 and from in-process to isolated."

@viktor11prykhidko
Copy link

viktor11prykhidko commented Nov 30, 2023

But then next problem will come I think. Please confirm if you get the same as me when trying to build your project:

Screenshot 2023-11-30 115846

It error says: "The type or namespace name 'Azure' does not exist in the namespace '[your namespace]' (are you missing an assembly reference?)

I added specified usings, build is ok
image

but http://localhost:7071/api/swagger/ui loading endless

@justinyoo
Copy link
Contributor

.NET 8 doesn't support in-process worker as of now. More precisely, .NET 8 "delayed" supports the in-process worker. Therefore, you can't use .NET 8 for your in-process worker.
Please refer to this page:

.NET 8 will at first only be available on the isolated worker model. There will be an initial preview soon, and we remain committed to full support on the isolated worker model the same day that .NET 8 becomes generally available. However, there will not be an in-process equivalent at the same time. That will come in a subsequent release in early 2024, and we will be doing what we can to make it available as soon as possible. So, if you are looking to use .NET 8 right when it comes out, you will have an option with the isolated worker model. But if you wish to continue using the in-process model, there will be a slight delay.

He is using .NET 8 isolated process:) -> "I am attempting to migrate an Azure Function from .NET 6 to .NET 8 and from in-process to isolated."

Oops! My bad! I should have read more carefully.

@eat-sleep-code @remitonning Would you please be able to provide me with a sample repo so that I can repro on my end?

@eat-sleep-code
Copy link
Author

eat-sleep-code commented Nov 30, 2023

@justinyoo and @remitonning

I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

The documentation likely needs to be updated to clarify that.

Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?

image

@viktor11prykhidko
Copy link

viktor11prykhidko commented Nov 30, 2023

@justinyoo and @remitonning

I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

The documentation likely needs to be updated to clarify that.

Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?

image

try to add this .ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson()) in Program.cs

@eat-sleep-code
Copy link
Author

@viktor11prykhidko doing that results in your aforementioned never-ending loading scenario.

@davidpetric
Copy link

davidpetric commented Nov 30, 2023

@justinyoo and @remitonning

I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

The documentation likely needs to be updated to clarify that.

Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?

image

I have the exact same issue and was trying to figure out if the openapi nuget is compatible with aspnet integration, can't find any info on this topic..

Still wating on someone to confirm..
#628

@albertospelta
Copy link

albertospelta commented Dec 1, 2023

Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?

image

@eat-sleep-code This issue likely stems from the fact that the Azure Functions OpenAPI Extension hasn't been updated yet to fully support ASP.NET Core Integration in Azure Functions .NET isolated model. Swagger is trying to load the API definition using the isolated worker process port (dotnet.exe/55495) instead of using the webjobs host process port (func.exe/7071).

image

Updating the port in Swagger UI to localhost:7071/api/swagger.json should solve(workaround) the error.

@kshyju
Copy link
Member

kshyju commented Dec 3, 2023

But then next problem will come I think. Please confirm if you get the same as me when trying to build your project:

Screenshot 2023-11-30 115846

It error says: "The type or namespace name 'Azure' does not exist in the namespace '[your namespace]' (are you missing an assembly reference?)

@remitonning
Are you still seeing this error when using the latest version of Microsoft.Azure.Functions.Worker.Sdk package?

@joeliir
Copy link

joeliir commented Dec 6, 2023

@viktor11prykhidko doing that results in your aforementioned never-ending loading scenario.

I was able to get it to work by doing the following in the configuration which isn't pretty but at least locally it now runs.

services.AddSingleton(_ =>
{
  var options = new OpenApiConfigurationOptions
  {
    // Your normal options
  };
  
  options.IncludeRequestingHostName = false;
  options.Servers.Clear();

  if (hostContext.Configuration["WEBSITE_HOSTNAME"].Contains("localhost", StringComparison.InvariantCultureIgnoreCase))
  {
      options.Servers.Add(new OpenApiServer()
      {
          Url = $"http://{hostContext.Configuration["WEBSITE_HOSTNAME"]}/api"
      });
  }
  else
  {
      options.Servers.Add(new OpenApiServer()
      {
          Url = $"https://{hostContext.Configuration["WEBSITE_HOSTNAME"]}/api"
      });
  }
  
  return options;
});``` 

@slaneyrw
Copy link

slaneyrw commented Dec 7, 2023

For what it's worth to people, if you are adding the worker AspNetCore extensions, you can use a wrapped ForwardedHeadersMiddleware to patch the HttpRequest before the OpenApi function endpoint processes the request

// Program.cs
var host = new HostBuilder()
    .ConfigureFunctionsWebApplication(app =>
    {
        // get current request, and switch from http to https(request scheme), apply the options per request
        app.UseMiddleware<FunctionApp1.Middleware.ForwardedHeadersMiddleware>();
    })
    .ConfigureServices(services =>
    {
        services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
            options.KnownNetworks.Clear();
            options.KnownProxies.Clear();
        });
    })
    ...
// ForwardedHeadersMiddleware.cs
namespace FunctionApp1.Middleware
{
    public class ForwardedHeadersMiddleware : Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware, IFunctionsWorkerMiddleware
    {
        public ForwardedHeadersMiddleware(ILoggerFactory loggerFactory, IOptions<ForwardedHeadersOptions> options)
            : base( ctx => Task.CompletedTask, loggerFactory, options)
        {
            
        }
        public Task Invoke(FunctionContext context, FunctionExecutionDelegate next)
        {
            var httpContext = context.GetHttpContext();

            if (httpContext != default)
                this.ApplyForwarders(httpContext);

            return next(context);
        }
    }
}

@remitonning
Copy link

But then next problem will come I think. Please confirm if you get the same as me when trying to build your project:
Screenshot 2023-11-30 115846
It error says: "The type or namespace name 'Azure' does not exist in the namespace '[your namespace]' (are you missing an assembly reference?)

@remitonning Are you still seeing this error when using the latest version of Microsoft.Azure.Functions.Worker.Sdk package?

Hi @kshyju
I have fixed the error. It was a stupid mistake from my side. I had an old file lying in the projekt that was not doing anything. But it had a wrong name on the namespace. I did not know that swagger was so fussy about the naming of the namespaces. But it´s a good thing though. I could get rid of the unused class.

Best regards,
Remi

@remitonning
Copy link

remitonning commented Dec 7, 2023

@justinyoo and @remitonning
I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
The documentation likely needs to be updated to clarify that.
Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?
image

I have the exact same issue and was trying to figure out if the this openapi nuget is compatible with aspnet integration, can't find any info on this topic..

Still wating on someone to confirm.. #628

Hi @eat-sleep-code and @davidpetric

When you are using Azure Functions isolated (out-of-process) you should not use the using directives
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

and not use HttpRequest in your function(endpoint) as parameter. Instead use HttpRequestData
and not use IActionResult as result. Instead use HttpResponseData.

In you function you can than write for example:
HttpResponseData response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(result); // Or for example .WriteAsJsonAsync
return response;

Se image below for an example.

using directives:
image

Azure function endpoint:
image

Nuget-packages:
image

...and make sure you have
.ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson()
in Program.cs as @viktor11prykhidko mentioned.

Best regards,
Remi

@davidpetric
Copy link

davidpetric commented Dec 7, 2023

@justinyoo and @remitonning
I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
The documentation likely needs to be updated to clarify that.
Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?
image

I have the exact same issue and was trying to figure out if the this openapi nuget is compatible with aspnet integration, can't find any info on this topic..
Still wating on someone to confirm.. #628

Hi @eat-sleep-code and @davidpetric

When you are using Azure Functions isolated (out-of-process) you should not use the using directives using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc;

and not use HttpRequest in your function(endpoint) as parameter. Instead use HttpRequestData and not use IActionResult as result. Instead use HttpResponseData.

In you function you can than write for example: HttpResponseData response = req.CreateResponse(HttpStatusCode.OK); await response.WriteStringAsync(result); // Or for example .WriteAsJsonAsync return response;

Se image below for an example.

using directives: image

Azure function endpoint: image

Nuget-packages: image

...and make sure you have .ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson() in Program.cs as @viktor11prykhidko mentioned.

Best regards, Remi

Hi, thanks for getting back,

The problem is I am using AspNetCore integration which mostly works with OpenAPI(I had opened an issue to have an official answer but no one from the team responded)

The problem is that the Swagger will use a different PORT than the Azure function port for some reason...

image

@joeliir
Copy link

joeliir commented Dec 7, 2023

@justinyoo and @remitonning
I was able to get it to build with the following usings:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker; 
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

and the following decoration:

[Function("Get")]
[OpenApiOperation(operationId: "Run", tags: new[] { "name" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "email", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The email address of the lead you wish to retrieve")]
[OpenApiResponseWithBody(statusCode: System.Net.HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string), Description = "The OK response")]

But this is a bit off from the decoration that says to remove any Microsoft.Azure.WebJobs usings. I took this to mean to remove the using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; and using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
The documentation likely needs to be updated to clarify that.
Now can someone tell me why I get the following when trying to launch the Swagger UI in dev? Why is it trying to launch the swagger json on a different port than the app?
image

I have the exact same issue and was trying to figure out if the this openapi nuget is compatible with aspnet integration, can't find any info on this topic..
Still wating on someone to confirm.. #628

Hi @eat-sleep-code and @davidpetric
When you are using Azure Functions isolated (out-of-process) you should not use the using directives using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc;
and not use HttpRequest in your function(endpoint) as parameter. Instead use HttpRequestData and not use IActionResult as result. Instead use HttpResponseData.
In you function you can than write for example: HttpResponseData response = req.CreateResponse(HttpStatusCode.OK); await response.WriteStringAsync(result); // Or for example .WriteAsJsonAsync return response;
Se image below for an example.
using directives: image
Azure function endpoint: image
Nuget-packages: image
...and make sure you have .ConfigureFunctionsWorkerDefaults(worker => worker.UseNewtonsoftJson() in Program.cs as @viktor11prykhidko mentioned.
Best regards, Remi

Hi thanks for getting back,

Problem is I am using AspNetCore integration which mostly works with OpenAPI(I had opened a issue to have a official answer but no one from team responded)

The problem is that the swagger will use a different PORT than the azure function port for some reason..

image

Take a look at what I did to get it to work above #629 (comment)

@DannyBoyIT
Copy link

DannyBoyIT commented Dec 26, 2023

Take a look at what I did to get it to work above #629 (comment)

@joeliir Where do you get the hostContext from?

@DannyBoyIT
Copy link

When you are using Azure Functions isolated (out-of-process) you should not use the using directives
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

Why is that @remitonning?
Microsoft is in the documentation for upgrading to isolated process using exactly these usings.

@davidpetric
Copy link

Take a look at what I did to get it to work above #629 (comment)

@joeliir Where do you get the hostContext from?

it's from ConfigureServices extension method:
image

@joeliir
Copy link

joeliir commented Dec 30, 2023

Take a look at what I did to get it to work above #629 (comment)

@joeliir Where do you get the hostContext from?

This is a program.cs that works. You can see where I'm getting the hostContext from below:

using System;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

var host = new HostBuilder()
           .ConfigureFunctionsWebApplication()
           .ConfigureServices((hostContext, services) => {
               services.AddApplicationInsightsTelemetryWorkerService();
               services.ConfigureFunctionsApplicationInsights();

               services.AddSingleton<IOpenApiConfigurationOptions>(_ =>
               {
                   var options = new OpenApiConfigurationOptions
                   {
                       Info = new OpenApiInfo
                       {
                           Version = OpenApiVersionType.V3.ToString(),
                           Title = "",
                           Description = "",
                           TermsOfService = new Uri(""),
                           Contact = new OpenApiContact
                           {
                               Name = "",
                               Email = ""
                           }
                       },
                       Servers = DefaultOpenApiConfigurationOptions.GetHostNames(),
                       OpenApiVersion = OpenApiVersionType.V3,
                       IncludeRequestingHostName = DefaultOpenApiConfigurationOptions.IsFunctionsRuntimeEnvironmentDevelopment(),
                       ForceHttps = DefaultOpenApiConfigurationOptions.IsHttpsForced(),
                       ForceHttp = DefaultOpenApiConfigurationOptions.IsHttpForced(),
                   };

                   options.Servers.Clear();
                   options.Servers.Add(new OpenApiServer()
                   {
                       Url = $"http://{hostContext.Configuration["WEBSITE_HOSTNAME"]}/api"
                   });

                   if (hostContext.HostingEnvironment.IsDevelopment())
                   {
                       options.IncludeRequestingHostName = false;
                   }

                   return options;
               });
           }).Build();

host.Run();

@daedam
Copy link

daedam commented Jan 4, 2024

Thanks to @joeliir for the example shared above! It worked for me locally, but it failed when published because the function in Azure was running under https. I first tried using hostContext.HostingEnvironment to determine whether the URL should be http or https, but then I discovered it wasn't necessary. From the documentation and inspecting the source of the DefaultOpenApiConfigurationOptions class, I noticed you can use a server-relative path instead (i.e., /api). This Program.cs works for me in both local development and deployed to Azure Functions:

using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.OpenApi.Extensions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Abstractions;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Configurations;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;

var host = new HostBuilder()
    .ConfigureFunctionsWebApplication(builder => builder.UseNewtonsoftJson())
    .ConfigureServices(services =>
    {
        services.AddApplicationInsightsTelemetryWorkerService();
        services.ConfigureFunctionsApplicationInsights();

        services.AddSingleton<IOpenApiConfigurationOptions>(_ => new DefaultOpenApiConfigurationOptions
        {
            // The important parts:
            IncludeRequestingHostName = false,
            Servers = [new OpenApiServer { Url = "/api" }],

            // Optional settings:
            Info =
            {
                Version = "1.0.0", // Version of your API
                Title = "",
                Description = "",
                Contact = new OpenApiContact
                {
                    Name = "",
                    Email = ""
                }
            },
            OpenApiVersion = OpenApiVersionType.V3
        });
    })
    .Build();

host.Run();

Note that it's possible there are downsides to using a relative URL (/api), but if there are, I haven't discovered them yet.

@CNBoland
Copy link

@viktor11prykhidko @joeliir @eat-sleep-code
This appears to have been fixed in Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore 1.2.0. I've confirmed it working on my machine locally.

@patest-dev
Copy link

I think this was solved by PR Azure/azure-functions-dotnet-worker#2149 for this issue Azure/azure-functions-dotnet-worker#2071

@adavs6533
Copy link

I can't follow this thread. Did we indeed determine if these libraries are the correct ones to reference to use the OpenApi attributes?

using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

Because, as mentioned before, the documentation to migrate to the isolated model from in-proc clearly states in multiple places that references to the Microsoft.Azure.WebJobs.* namespaces should be removed.

https://learn.microsoft.com/en-us/azure/azure-functions/migrate-dotnet-to-isolated-model?tabs=net8#package-references

@CNBoland
Copy link

CNBoland commented Feb 14, 2024

I can't follow this thread. Did we indeed determine if these libraries are the correct ones to reference to use the OpenApi attributes?

using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes; using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;

Because, as mentioned before, the documentation to migrate to the isolated model from in-proc clearly states in multiple places that references to the Microsoft.Azure.WebJobs.* namespaces should be removed.

https://learn.microsoft.com/en-us/azure/azure-functions/migrate-dotnet-to-isolated-model?tabs=net8#package-references

Those two Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.* namespaces are in package Microsoft.Azure.WebJobs.Extensions.OpenApi.Core. That package targets .NET Standard 2.0 which makes it usable by both Azure Functions in-process and isolated process assemblies. There was no need to rewrite them with a Microsoft.Azure.Functions.Worker.* namespace. The difference is indeed a little confusing.

@Chethan31
Copy link

Chethan31 commented Jun 27, 2024

Hi, I'm currently integrating Azure Functions with Swagger. I've successfully done this for .NET 6.0, and now I'm exploring a proof of concept (POC) using .NET 8.0. Could someone please provide a step-by-step guide or share documentation and sample code that demonstrates the integration of Swagger with Azure Functions in .NET 8? It would be greatly appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests