Swashbuckle root error when i deploy on subfolder - api

I begin with Swashbuckle, i make a Web API in .NET Core with Swashbuckle.
I need to deploy my API in a sub-application of an IIS site
IIS infrastructure
IIS Site (site)
myApi (subApplication)
http://ip:80/myApi
I would like the access to swagger UI to be done via this url :
http://ip:80/myApi/swagger
I would like the access to the methods to be done by this url :
http://ip:80/myApi/api/[controller]/methode
ConfigureServices(IServiceCollection services)
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info { Title = "My REST API", Version = "v1" });
});
Configure(IApplicationBuilder app..)
if (env.IsEnvironment("ProdIT"))
{
app.UseSwagger(c =>
{
c.PreSerializeFilters.Add((swaggerDoc, httpReq) => swaggerDoc.BasePath = "/myApi/");
c.RouteTemplate = "myApi/api-docs/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "myApi/swagger";
c.SwaggerEndpoint("/myApi/api-docs/v1/swagger.json", "MY REST API V1");});
Route Controller
[Route("api/[controller]")]
Could you tell me what's wrong with my code?
Thanks in advance

I had the same issue and I resolved it by configuring the SwaggerUI like that;
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("v1/swagger.json", "MY REST API V1");});
}

Related

Web API method not fetching data after adding OData functionality

I am using ASP.NET Core 2.1 Web API with Angular 6 as frontend.
I have added OData functionality to the Startup.cs file in the Web API project. I also use Swagger to document the API.
This is the code in the Startup.cs file for ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddOData();
services.AddCors();
services.AddMvc(opt =>
{
opt.UseGeneralRoutePrefix("BookManagement");
opt.SslPort = SettingsLoader<AppSettings>.Settings.SslPort;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); ;
services.AddMvcCore(options =>
{
foreach (var outputFormatter in options.OutputFormatters.OfType<OutputFormatter>().Where(x => x.SupportedMediaTypes.Count == 0))
{
outputFormatter.SupportedMediaTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
foreach (var inputFormatter in options.InputFormatters.OfType<InputFormatter>().Where(x => x.SupportedMediaTypes.Count == 0))
{
inputFormatter.SupportedMediaTypes.Add(new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddRequestScopingMiddleware(() => _scopeProvider.Value = new Scope());
services.AddCustomControllerActivation(Resolve);
services.AddCustomViewComponentActivation(Resolve);
// Register the Swagger generator, defining 1 or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc($"v{AppVersion.cVersion}", new Info { Title = "Books Microservice", Version = $"v{AppVersion.cVersion}" });
c.IncludeXmlComments(Path.Combine(Environment.CurrentDirectory, "Synergy.AssetsModule.WebApi.xml"));
});
}
Configure method is as below
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
Kernel = RegisterApplicationComponents(app);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
if (SettingsLoader<AppSettings>.Settings.AutoUpdateDatabase)
{
IDatabaseLogic databaseLogic = new DatabaseLogic(Kernel.Get<IDatabasePersistence>());
databaseLogic.UpgradeDatabase();
}
InitiateMessageReprocess();
#if !NO_AUTH
ISingleSignOnLogic singleSignOnLogic = Kernel.Get<ISingleSignOnLogic>();
app.UseMiddleware<AuthenticationFilter>(singleSignOnLogic);
#endif
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"/swagger/v{AppVersion.cVersion}/swagger.json", $"Books Microservice API v{AppVersion.cVersion}");
c.RoutePrefix = string.Empty;
});
app.UseCors(builder =>
{
builder.AllowAnyOrigin();
builder.AllowAnyMethod();
builder.AllowAnyHeader();
});
app.UseMvc(routeBuilder =>
{
routeBuilder.EnableDependencyInjection();
routeBuilder.Expand().Select().Count().OrderBy().Filter();
});
app.UseRewriter(new RewriteOptions().AddRedirectToHttps(StatusCodes.Status301MovedPermanently, SettingsLoader<AppSettings>.Settings.SslPort));
LogProvider.Instance.LogInformation("Started application");
}
With this code, the Swagger API is returning 204 Undocumented.
Don't know where it is going wrong. The parameter content type previously I was using is application/json-patch+json. Please suggest why I am not getting the data from the Web API method.
A couple of things. First, I would suggest creating a separate web service to host your OData endpoints. Second, prior to .net 6, it's somewhat difficult to get OData and Swagger to work together. Even in .net 6, there are a few things missing when it comes to swagger.
I have an open-source project that fills in the gaps. Here's a sample project that illustrates how to use it.
https://github.com/ikemtz/NRSRx/tree/master/samples/IkeMtz.Samples.OData

.NET 5 API add Access-Control-Allow-Origin headers - with Ionic 5.5

Can you please assist, I have a .NET 5 Web API and Ionic 5.5 app. I have deployed the API and the Ionic app to Azure Web Services. The API is serving the Ionic app, so they are on the same domain - I can say same origin because the scheme, and domain are the same.
The issue is that, the Ionic app is failing to call the API because it seems like CORS is blocking it.
In my API, I have allowed any origin, any header and credentials but it's still not working. I have attached my Startup.cs file for the .NET 5 API.
Startup.cs code
using AutoMapper;
using EventManager.Business.Repositories;
using EventManager.Database;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Versioning;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Reflection;
namespace EventManager.Api
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
//options.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
services.AddControllers();
services.AddApiVersioning(x =>
{
x.DefaultApiVersion = new ApiVersion(2, 1);
x.AssumeDefaultVersionWhenUnspecified = true;
x.ReportApiVersions = true;
// Supporting multiple versioning scheme
x.ApiVersionReader = new UrlSegmentApiVersionReader();
});
services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = false;
});
var mappingConfig = new MapperConfiguration(mc =>
{
mc.AddProfile(new Business.MappingProfile());
});
var mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Event Manager API Documentation",
Version = "v1",
Contact = new OpenApiContact
{
Email = "eric#xxxxx.com",
Name = "Eric Smith",
Url = new Uri("https://www.xxxxx.org/")
},
Description = #"Used for as a self-service for event attendees.
To capture attendee details and print out attendee badges",
License = new OpenApiLicense
{
Name = "Use under LICX",
Url = new Uri("https://www.xxxxx.org/api/license"),
}
});
//Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
services.AddDbContext<AppDbContext>(x => x.UseSqlServer(Configuration.GetConnectionString("MSSqlConnection"),
b => b.MigrationsAssembly("EventManager.Database")));
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<EventRepository>();
services.AddScoped<AttendeeRepository>();
services.AddScoped<DesignationRepository>();
services.AddScoped<EntryQuestionRepository>();
services.AddScoped<EntryQuestionSectionRepository>();
//Sart: To serve angular app
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "ClientApp"; });
//End: To serve angular app
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "EventManager.Api v1"));
}
app.UseRouting();
app.UseCors(builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
app.UseAuthorization();
//Start: To serve angular app
app.UseDefaultFiles();
app.UseSpaStaticFiles();
//End: To serve angular app
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//Start: To serve angular app
app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; });
//End: To serve angular app
}
}
}
My API call from the Ionic app
headers = new HttpHeaders({
"Authorization": "Bearer " + "XXXXXXX",
"Content-Type": "application/json"
});
//environment.api = 'https://myazureappname.azurewebsites.net/api/'
get(cellNumber?: string): Observable<AttendeeGetModel[]> {
return this._http.get<AttendeeGetModel[]>(`${environment.api}v1/attendees?cellNumber=${cellNumber}`, { headers: this.headers });
}
**Error message from Firefox browser attached**
[![enter image description here][1]][1]
The error ERR_NAME_NOT RESOLVED typically means: Chrome cannot resolve the domain name which in most cases means you're using the wrong domain name or have a typo.
In your case it looks like your're using the wrong top level domain in your app. Postman = ".net", Your app = ".com".

How swagger authentication works?

Hi I have developed swagger UI for my .net core web application. I have added authentication to it. I have registered two applications in my Azure AD. One for Swagger and one for Back end .Net core app. Below is my code.
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = swaggerUIOptions.AuthorizationUrl,
TokenUrl = swaggerUIOptions.TokenUrl
});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new[] { "readAccess", "writeAccess" } }
});
});
In the above code I am indicating type and flow. Also specifying AuthorizationUrl and token url. When coming to scopes, If I add scopes then that means my Swagger has access to added scopes or my back end api has access to those scopes? Then I have below code.
c.OAuthClientId(swaggerUIOptions.ClientId);
c.OAuthClientSecret(swaggerUIOptions.ClientSecret);
c.OAuthRealm(azureActiveDirectoryOptions.ClientId);
c.OAuthAppName("Swagger");
c.OAuthAdditionalQueryStringParams(new { resource = azureActiveDirectoryOptions.ClientId });
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
When we develop swagger, We are getting access token for swagger app or back end app? Also I have c.OAuthRealm and passing my back end app client id. What this line of code do actually? Also when I add [Authorize] attribute in top of my API and then If i try to hit api directly It will not work. It will work only after authentication. So how Authorize attribute works exactly? Can someone help me to understand these things? Any help would be appreciated. Thanks
Regarding how to configure Swagger to authenticate against Azure AD, please refer to the following steps
Configure Azure AD for your web API. For more details, please refer to the document
a. Create Azure AD web api application
b. Expose API
c. Configure code
config file
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "[Client_id-of-web-api-eg-2ec40e65-ba09-4853-bcde-bcb60029e596]",
"TenantId": "<your tenant id>"
},
Add following code in the Stratup.cs
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
.AddAzureADBearer(options => Configuration.Bind("AzureAd", options));
Configure swagger. For more details, please refer to the blog.
a. Create Azure Web application
b. Configure API permissions. Regarding how to configure, you can refer to the document
c. code
Install SDK
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
Add the following code to Startup.cs in the ConfigureServices method:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = $"https://login.microsoftonline.com/{Configuration["AzureAD:TenantId"]}/oauth2/authorize",
Scopes = new Dictionary<string, string>
{
{ "user_impersonation", "Access API" }
}
});
c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new[] { "user_impersonation" } }
});
});
Add the following code to the Configure method:
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.OAuthClientId(Configuration["Swagger:ClientId"]);
c.OAuthClientSecret(Configuration["Swagger:ClientSecret"]);
c.OAuthRealm(Configuration["AzureAD:ClientId"]);
c.OAuthAppName("My API V1");
c.OAuthScopeSeparator(" ");
c.OAuthAdditionalQueryStringParams(new { resource = Configuration["AzureAD:ClientId"] });
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});

Asp.net core swagger not found and server error

I have installed Swashbuckle.AspNetCore version 4.0.1 and tried all solutions and ways. Maybe this is duplicate it's not working in IIS.
I always get not found error or internal server error.
This is my Startup.cs.
// Configure Services
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new Info { Title = "Shop API", Version = "v1" });
});
// Configure
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
//c.RoutePrefix = string.Empty;
});
app.UseMvc();
Did anybody tried latest version?
I'm using the same version as your. Mine below config look like this
ConfigureServices
// Register the Swagger generator, defining one or more Swagger documents
services.AddMvc();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Awesome CMS Core API V1",
Contact = new Contact { Name = "Tony Hudson", Email = "", Url = "https://github.com/ngohungphuc" }
});
c.SwaggerDoc("v2", new Info
{
Version = "v2",
Title = "Awesome CMS Core API V2",
Contact = new Contact { Name = "Tony Hudson", Email = "", Url = "https://github.com/ngohungphuc" }
});
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
Configure
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint($"/swagger/v1/swagger.json", "Awesome CMS Core API V1");
c.SwaggerEndpoint($"/swagger/v2/swagger.json", "Awesome CMS Core API V2");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
I'm just having 2 API version so it's not important in your case
Make sure your middleware are in correct order like mine
Please let me know if you have any problem

.NetCore Swagger can not work

I took long time to try to configure swagger for my .netCore project.
the following steps I have done, but not successful :-(
Nuget Package:
Swashbuckler.SwaggerGen,
Swashbuckler.SwaggerUi,
in ConfigureServices Method
instance.AddMvc();
instance.AddSwaggerGen();
in Config Method
instance.UseMvc();
instance.UseSwagger();
instance.UseSwaggerUi();
I rebuild my project, and go to link http://localhost:5000/swagger/ui
came error: localhost refused to connect.ERR_CONNECTION_REFUSED
Can anybody help me??
BR,
Leon
This is what I have in my aspnet core rest api project.
In ConfigureServices method:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Title = "MyProject - HTTP API",
Version = "v1",
Description = "My project HTTP API."
});
});
In the Configure method:
app.UseSwagger().UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProj HTTP API v1");
});
Then simply navigate to http://localhost:56468/swagger/ where 56468 is the port my application is running on.
You should include NuGet package Swashbuckle.AspNetCore for swagger configuration. Add below code in Configure section of Startup.cs
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
And add below code in ConfigureServices section of Statup
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo() { Title = "My API", Description = "My API V1" });
});