.NET has the ability to auto-generated OpenAPI specifications based on your code. You can use different decorators on your code like ProducesResponseTypeAttribute or ConsumesAttribute to produce more descriptive response details for web API help pages generated by tools like Swagger.

What if you didn’t want to use the autogenerated spec, what if you instead wanted to expose an already written spec, perhaps because you follow an API-first approach to building an API instead of a Code-First approach. How would you expose that OpenAPI file?

Turns out the answer is pretty straightforward. .NET already supports the ability to expose static files via the wwwroot folder, unlike an MVC project an API project does not come with the wwwroot folder, but that doesn’t mean you can’t add it yourself.

So if you wanted to expose an OpenAPI spec file or any other kind of file via an API add a new folder on under the Web API project and name the folder wwwroot.

Simply putting the file there is not enough, .NET doesn’t expose files simply because they are located in the wwwroot folder, you have to enable file browsing by using the UseStaticFiles middleware in code, for example.

var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.UseHttpsRedirection();
app.UseStaticFiles(); // Enables file browsing on wwwroot.
app.UseAuthorization();

app.Run();

With the middleware enabled you should be able to retrieve any files under wwwroot. Say that I place the OpenAPI file in the following file directory.

wwwroot/Swagger/v1/swagger.json

To retrieve the file by HTTP I would need to submit a request to the following URL.

https://<hostname>/swagger/v1/swagger.json

Something worth mentioning, .NET by default will only serve files that have a media type as defined in Media Types. If the file you are attempting to serve does not have a supported mime type, the API will return a 404. To bypass this feature you will need to use the FileExtensionContentTypeProvider class to add additional media type mappings.

For example, as of June 2023, YAML is not part of the media types supported by .NET because it does not have an official media type even though you may see apps like Google Chrome accept application/yaml and text/yaml, see this IANA Proposal to learn more. If attempt to expose a YAML file through we .NET Web API, the API will only serve a 404 NOT FOUND response. You would need to use the following code to expose any media type not currently supported by .NET.

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
var provider = new FileExtensionContentTypeProvider();

// Add new mappings
provider.Mappings[".yaml"] = "text/yaml"; // Allow YAML files to be served via HTTP request.

app.UseStaticFiles(new StaticFileOptions
{
    ContentTypeProvider = provider
});

app.UseSwagger();
app.UseSwaggerUI(c=>c.SwaggerEndpoint("/swagger/v1/swagger.yaml", "v1")); // Path to file location.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

With the code above you can now expose any file over HTTP, you can learn more about how .NET deals with files by reading the Static files in ASP.NET Core doc.

Quick note, as of June 2023 .NET only supports OpenAPI version 3.0.n, anything higher will result in an error, see 795 for more details.