C# web api swagger integration - c#

I have a problem to integrate swagger ui with my web api, and i don't have any idee what is the problem.
When i call in the browser the swagger, the page http://localhost:56381/swagger/ui/index is like in this screenshot
In the SwaggerConfig.cs file i have this code:
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace dummyNamespace
{
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c => c.SingleApiVersion("v1", "Test API"))
.EnableSwaggerUi();
}
}
}
I follow this tutorial: http://www.wmpratt.com/swagger-and-asp-net-web-api-part-1/ . But not working.
I don't now what is wrong with my configuratio.
I use .net framework 4.5.2, Web api 2.0 and Swashbuckle.5.5.3 version
Update:
When I call this url
http://localhost:56381/swagger/docs/v1
Return this image:
Update1:
After i put this code in my WebApiConfig.cs:
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
Now the http://localhost:56381/swagger/ui/index return this json:
{
"statusCode": 200
}
Any idee how to make make http://localhost:56381/swagger/ui/index return this page:
The page is from a test project.

After reading the tutorial you posted, it looks like somehow your root URL may be different than what swagger expects. From the swagger config file:
// By default, the service root url is inferred from the request used to access the docs.
// However, there may be situations (e.g. proxy and load-balanced environments) where this does not
// resolve correctly. You can workaround this by providing your own code to determine the root URL.
//
//c.RootUrl(req => GetRootUrlFromAppConfig());
If that is not the case, it could be that the swashbuckle nuget install is somehow corrupted. Try removing the nuget package and reinstalling it.

Related

Adding comments to endpoints w/ Swagger

I'm using Swagger / Swashbuckle for my API. I want the Swagger UI to show the method descriptions. In their documents it says:
2 - Configure Swashbuckle to incorporate the XML comments on file into the generated Swagger JSON:
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1",
new Info
{
Title = "My API - V1",
Version = "v1"
}
);
var filePath = Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml");
c.IncludeXmlComments(filePath);
}
Can someone please explain this? What I am supposed to do with this code? Do I copy and paste it somewhere? If so, where?
(.NET Framework 4.7)
EDIT:
The answer by Jawad below led me to the solution. In the original SwaggerConfig.cs file, there was this:
// If you annotate Controllers and API Types with
// Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate
// those comments into the generated docs and UI. You can enable this by providing the path to one or
// more Xml comment files.
//
//c.IncludeXmlComments(GetXmlCommentsPath());
I was unclear on how to change that last line to add my XML file. This worked:
c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "bin\\KGC.API.xml"));
I also had to add using System.IO.
The way i have done it is by updating the SwaggerConfig.cs file ..
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger("docs/{apiVersion}", c =>
{
c.SingleApiVersion("v1", "Title Of API");
c.Schemes(new List<string> { "http", "https" });
c.UseFullTypeNameInSchemaIds();
c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml"));
});
}
Last line in the code above enabled the XML comment tagging.
One other thing you have to do is,
Go to Properties of Project (not Solution)
Build / Output -> Add path to XML Documentation File.
For Reference Purposes, this was quite helpful.

NSwag .NET Core API Versioning configuration

I'd like to prepare my .NET Core Web API project so that multiple versions of the API can be managed and documented, according to the REST services standards.
I'm using .NET Core 2.1 with NSwag (v11.18.2). I also installed the Microsoft.AspNetCore.Mvc.Versioning NuGet package.
I already searched with Google for some configuration examples, but the only useful link I found is this.
I'm now able to get Swagger pages for both API versions but with some problems:
Please note that none of the last config settings (Title, Description, etc.) takes effect on any of the 2 routes. It only works if I add them on each of the individual configuration. So I'd also like to know if it possible to avoid that, since the general configuration of the API can be version indipendent (title, description and so on...).
Since the issue with NSwag and Microsoft API Versioning package discussed in the above link, was opened 2-3 months (and NSwag versions too) ago, I'd like to know if it is now truly fixed and in this case, which is the right configuration to set.
Although the version is explicit in the configuration of the controllers, it is still required as a mandatory input parameter of the controller methods and of course I don't want that! See image:
So, my actual configuration, by following that example, is looking like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddApiVersioning(options =>
{
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
options.ReportApiVersions = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSwaggerWithApiExplorer(config =>
{
config.GeneratorSettings.OperationProcessors.TryGet<ApiVersionProcessor>().IncludedVersions = new[] { "1.0" };
config.SwaggerRoute = "v1.0.json";
});
app.UseSwaggerWithApiExplorer(config =>
{
config.GeneratorSettings.OperationProcessors.TryGet<ApiVersionProcessor>().IncludedVersions = new[] { "2.0" };
config.SwaggerRoute = "v2.0.json";
});
app.UseSwaggerUi3(typeof(Startup).GetTypeInfo().Assembly, config =>
{
config.SwaggerRoutes.Add(new SwaggerUi3Route("v1.0", "/v1.0.json"));
config.SwaggerRoutes.Add(new SwaggerUi3Route("v2.0", "/v2.0.json"));
config.GeneratorSettings.Title = "My API";
config.GeneratorSettings.Description = "API functionalities.";
config.GeneratorSettings.DefaultUrlTemplate = "{v:apiVersion}/{controller}/{action}/{id?}";
config.GeneratorSettings.DefaultPropertyNameHandling = PropertyNameHandling.CamelCase
});
}
And these are my actual controllers:
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[SwaggerTag("Test1", Description = "Core operations on machines (v1.0).")]
public class MachinesController : Controller
{
[HttpGet("{id}")]
[ProducesResponseType((int)HttpStatusCode.OK)]
public async Task<ActionResult<Machine>> Get(int id)
{
return await ...
}
}
[ApiController]
[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[SwaggerTag("Test2", Description = "Core operations on machines (v2.0).")]
public class MachinesController : Controller
{
[HttpGet("{id}")]
[ProducesResponseType((int)HttpStatusCode.OK)]
public async Task<ActionResult<Machine>> Get(int id)
{
return await ...
}
}
They are ignored in the middleware because they are inferred from the settings or do not apply for api explorer (template). However title and description should work...
Please create an issue with the specific issue and a repro, also check out the existing tests in the repo
Fixed with v11.18.3
I believe starting in NSwag 12.0.0, there is significantly improved support for the API Explorer. It's important that the complementary API Explorer package for API versioning is also referenced so that the proper information is provided to NSwag.
The Swagger sample application provided by API Versioning uses Swashbuckle, but the setup will be very similar to NSwag. You can use the IApiVersionDescriptionProvider service to enumerate all of the API versions defined in your application. That should significantly simplify your NSwag configuration.
You're versioning by URL segment; therefore, to address Problem 3 you simply need to configure the API Explorer a la:
services.AddVersionedApiExplorer( options => options.SubstituteApiVersionInUrl = true );
This will replace the {version} route parameter in the route template with the corresponding API version value and remove the API version parameter from the API description.

Swagger UI - Web API versioning when using Microsoft.AspNet.WebApi.Versioning

We are using Web API 2 on our project with Swagger. My problem is that when Microsoft.AspNet.WebApi.Versioning is applied as following:
the Swagger UI is ignoring the fact that now I have version in my API which needs to be provided.
I looked at several examples but none seem to address this issue in a satisfying manner.
How do I force Swagger to let me add the API version or just add the version number automatically to the URL?
Swagger configuration so far:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "MoovShack.ServerApi");
// If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion".
// In this case, you must provide a lambda that tells Swashbuckle which actions should be
// included in the docs for a given API version. Like "SingleApiVersion", each call to "Version"
// returns an "Info" builder so you can provide additional metadata per API version.
//
//c.MultipleApiVersions(
// (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
// (vc) =>
// {
// vc.Version("v2", "Swashbuckle Dummy API V2");
// vc.Version("v1", "Swashbuckle Dummy API V1");
// });
c.OperationFilter<MoovShackTokenHeaderParameter>();
})
.EnableSwaggerUi(c =>
{
// If your API has multiple versions and you've applied the MultipleApiVersions setting
// as described above, you can also enable a select box in the swagger-ui, that displays
// a discovery URL for each version. This provides a convenient way for users to browse documentation
// for different API versions.
//
//c.EnableDiscoveryUrlSelector();
});
You can see that so far MultipleApiVersions are disabled - from one good reason as it doesn't produce any results. Especially since I am not sure what "ResolveVersionSupportByRouteConstraint" should do.
I also read that "EnableDiscoveryUrlSelector" has some kind of impact but I am also not sure if that applies to my case. When I enabled it, nothing happened.
We use it like this in our project and swagger recognizes it and it looks fine
[ApiVersion( "1.0" )]
[Route("api/v{version:apiVersion}/[controller]")]
public class SomeControlelr: Controller{
[HttpGet("", Name = "Someaction"), MapToApiVersion("1.0")]
public async Task<IActionResult> SomeAction(string someParameter)

web api with swagger versioning, ResolveVersionSupportByRouteConstraint not found

I have the api portion working but in my swaggerconfig it cannot find ResolveVersionSupportByRouteConstraint in
c.MultipleApiVersions(
(apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
(vc) =>
{
vc.Version("v2", "Swashbuckle Dummy API V2");
vc.Version("v1", "Swashbuckle Dummy API V1");
});
This causes my api import into azure api management to fail because the swagger docs returns an error :(
You have to create the method yourself. You may have to tweak the logic for your versioning scheme. Also, this method doesn't seem to get called for me when I choose a different version in the swashbuckle ui. This does get called on load, or if you request the doc via /swashbuckle/docs/.
public static bool ResolveVersionSupportByRouteConstraint(ApiDescription apiDesc, string targetApiVersion)
{
return apiDesc.ID.Contains($"/{targetApiVersion}/");
}

Adding Swashbuckle to the project causes error "Make sure that controller has a parameterless public constructor"

I have a project using OWIN. The whole solution consists of five parts:
Web application
Core
Infrastructure
WebApi
Tests
The project works well.
Recently, I planned to put swagger in my project. After some research, I decided to use Swashbuckle. https://github.com/domaindrivendev/Swashbuckle#custom-routes
I followed its tutorial by adding the following code to my Startup.cs:
HttpConfiguration Config = new HttpConfiguration();
WebApiConfig.Register(Config);
Config.EnableSwagger((c) =>
{
c.SingleApiVersion("v1", "Flynn Forms");
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
}).EnableSwaggerUi();
app.UseWebApi(Config);
Then, I did my API documentation at http://localhost:22391/swagger/ui/index. However, all my APIs stopped working. I got errors of my controllers such as:
An error occurred when trying to create a controller of type 'FormTemplateController'. Make sure that the controller has a parameterless public constructor.
I did not have a parameterless constructor... But it worked well before adding the Swashbuckle. I googled this error, someone suggested that just adding a parameterless constructor will solve this error. So my controller became:
[RoutePrefix("api/develop")]
public class FormTemplateController : ApiController
{
private IFormTemplateService formTemplateService;
public FormTemplateController()
{
}
public FormTemplateController(IFormTemplateService formTemplateService)
{
this.formTemplateService = formTemplateService;
}
[Route("form/{formId}")]
[HttpGet]
public FormTemplateEntity GetActiveFormTemplateByformId(string formId)
{
FormTemplateEntity formTemplate = formTemplateService.GetActiveFormTemplateEntityByFormId(formId);
return formTemplate;
}
....(different APIs)
}
The error did has gone. But I am now getting a new error indicating that formTemplateService is null.
I am using Castle Windsor as Inversion of Control container for my project. Does Swashbuckle have some conflicts with Castle Windsor? Does anyone have same issue and get a solution? I am not sure if I have provided enough background information. If you need more information, please leave them in the comments.
Thank you.
After trying different methods, I found the following works.
At first, I put the codes:
HttpConfiguration Config = new HttpConfiguration();
WebApiConfig.Register(Config);
Config.EnableSwagger((c) =>
{
c.SingleApiVersion("v1", "Flynn Forms");
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
}).EnableSwaggerUi();
app.UseWebApi(Config);
in Startup.cs cause I thought this is the entrance of my solution.
Then, I notice in my WebApi part, I have a file called WebApiConfig.cs which configs the instance of HttpConfiguration as well. So I moved codes to this file. (Because there has already been an instance of HttpConfiguration there, you don't have to create it again.) Just put the following codes there:
Config.EnableSwagger((c) =>
{
c.SingleApiVersion("v1", "Flynn Forms");
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
}).EnableSwaggerUi();
The problem got solved.

Categories