I am using Swagger UI to test my ASP.NET Web Api app. I added a class to allow operation parameters
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();
operation.Parameters.Add(new OpenApiParameter
{
Name = "ApiKey",
In = ParameterLocation.Header,
Required = true,
Schema = new OpenApiSchema
{
Type = "String"
}
});
operation.Parameters.Add(new OpenApiParameter
{
Name = "Authentication",
In = ParameterLocation.Header,
Required = false,
Schema = new OpenApiSchema
{
Type = "String"
}
});
}
In my Startup.cs, I added this line to the ConfigurationServices method
c.OperationFilter<CustomHeaderSwaggerAttribute>();
When I try and test one of the controller methods, my ApiKey string parameter always show an error no matter what I put in the textbox.
I am not sure about the Schema property but the following worked for me in past (setting the type to string):
operation.Parameters.Add(new Parameter
{
name = "ApiKey",
#in = ParameterLocation.Header,
required = true,
type = "string"
});
For more details, refer to this post
Related
I'm trying to find a way to apply a header for every request to an ASP NET Core application using Swagger UI. The thing is, then I use something like IOperationFilter:
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
operation.Parameters = new List<OpenApiParameter>();
operation.Parameters.Add(new OpenApiParameter
{
Name = "VeryImportantHeader",
In = ParameterLocation.Header,
Required = true,
Schema = new OpenApiSchema
{
Type = "String"
}
});
}
It adds a placeholder, which you should manually fill for every request, and that's kinda irritating, especially if you need to test lots of queries.
Is there a way to add a header, that will be applied to every request automatically?
For example, you can do that for the authorization, using AddSecurityDefinition:
single header placeholder example
I was looking for solution and After some search i couldn't found anything.So eventually i found a solution myself. It's probably too late for you but i put the solution here for others like me .
public class AuthorizationHeaderParameterOperationFilter:IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
operation.Security ??= new List<OpenApiSecurityRequirement>();
var tenantId = new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Tenant-Id" } };
var userId = new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "User-Id" } };
operation.Security.Add(new OpenApiSecurityRequirement
{
[tenantId] = new List<string>(),
[userId] = new List<string>()
});
}
}
after creating this class. On Startup
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("Tenant-Id", new OpenApiSecurityScheme
{
Name = "Tenant-Id",
In = ParameterLocation.Header,
Description = "Tenant Id",
Type = SecuritySchemeType.ApiKey
});
options.AddSecurityDefinition("User-Id", new OpenApiSecurityScheme
{
Name = "User-Id",
In = ParameterLocation.Header,
Description = "User Id",
Type = SecuritySchemeType.ApiKey
});
options.OperationFilter<AuthorizationHeaderParameterOperationFilter>();
});
Swagger UI Result :
request log :
I am trying to use Swagger with existing parameters. Adding in ODataQueryOptions removes All my other parameters in Swagger. How can I fix this to see my parameters? Code is below:
[HttpGet("[action]/{rollType}/{assessmentYear}/{lkAssessmentStatus}/{eventId?}")]
[ProducesResponseType(typeof(PageResult<BasicAssessmentDetailsDto>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(PageResult<BasicAssessmentDetailsDto>), StatusCodes.Status500InternalServerError)]
public ActionResult GetBasicPropertyAssessments(
int rollType,
int assessmentYear,
int lkAssessmentStatus,
int? eventId,
ODataQueryOptions<BasicAssessmentDetailsDto> queryOptions)
{
var result = assessmentRollService.GetBasicPropertyAssessmentsQueryable(rollType, assessmentYear, lkAssessmentStatus, eventId).ToODataPageResult(queryOptions);
return Ok(result);
}
We added the following in Startup, and yet is still not working:
services.AddOData();
services.AddControllers().AddNewtonsoftJson();
services.AddMvc(options =>
{
foreach (var outputFormatter in options.OutputFormatters.OfType<ODataOutputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
foreach (var inputFormatter in options.InputFormatters.OfType<ODataInputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
}
Add the following to Configure method
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.EnableDependencyInjection();
endpoints.Select().Expand().Filter().OrderBy().MaxTop(1000).Count();
});
namespace Common.OData
{
/// <summary>
/// This class allows us to add OData to our endpoints in swagger.
/// </summary>
public class ODataParametersSwaggerDefinition : IOperationFilter
{
private static readonly Type QueryableType = typeof(IQueryable);
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var parameterDescriptions = context.ApiDescription.ParameterDescriptions;
foreach (var parameter in parameterDescriptions)
{
// identify if any of the response types of the end point
// return a queryable type.
if (parameter.Type == typeof(ODataQueryOptions) || parameter.Type.IsSubclassOf(typeof(ODataQueryOptions)))
{
// the schema of our new parameter (string)
var schema = new OpenApiSchema { Type = "string" };
operation.Parameters.Clear();
// $filter
operation.Parameters.Add(new OpenApiParameter
{
Name = "$filter",
Description = "Filter the results using OData syntax.",
Required = false, // these are all optional filters, so false.
In = ParameterLocation.Query, //specify to pass the parameter in the query
Schema = schema
});
// $orderby
operation.Parameters.Add(new OpenApiParameter
{
Name = "$orderby",
Description = "Order the results using OData syntax",
Required = false,
In = ParameterLocation.Query,
Schema = schema
});
// $skip
operation.Parameters.Add(new OpenApiParameter
{
Name = "$skip",
Description = "Skip the specified number of entries",
Required = false,
In = ParameterLocation.Query,
Schema = schema
});
// $top
operation.Parameters.Add(new OpenApiParameter
{
Name = "$top",
Description = "Get the top x number of records",
Required = false,
In = ParameterLocation.Query,
Schema = schema
});
}
}
}
We do not see additional parameters
Currently using Net Core 3.1
I am documenting the API of my application through Swagger, which works with validation through a session token, that is, through a username and password a token is generated for a certain time that allows the user to navigate the site. What I need is for swagger to capture this session token and place it in the header of the requests for the rest of the API methods automatically, the only thing I could achieve so far is to pass the token as a parameter, but doing it manually. The idea is to make it automatic. I leave the configuration of SwaggerConfig.cs that I carry for now.
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
// HABILITAMOS SWAGGER.
.EnableSwagger(c =>
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory + #"\bin\";
var commentsFileName = Assembly.GetExecutingAssembly().GetName().Name + ".xml";
var commentsFile = Path.Combine(baseDirectory, commentsFileName);
c.SingleApiVersion("v1", "API");
c.OperationFilter<AddRequiredHeaderParameter>();
c.PrettyPrint();
c.ApiKey("apikey")
.Description("API Key Authentication")
.Name("Bearer")
.In("header");
c.IgnoreObsoleteActions();
c.IgnoreObsoleteProperties();
c.DescribeAllEnumsAsStrings();
.EnableSwaggerUi(c =>
{ c.DocumentTitle("DocumentaciĆ³n API");
c.EnableApiKeySupport("apikey", "header");
});
}
}
In turn, add a class to validate the application from where it is made on request
public class AddRequiredHeaderParameter : IOperationFilter
{
public void Apply(Swashbuckle.Swagger.Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters == null)
operation.parameters = new List<Parameter>();
operation.parameters.Add(new Parameter
{
name = "AuthorizedClient",
#in = "header",
type = "intenger",
description = "Aplicacion",
required = true,
#default = axaxax
});
operation.parameters.Add(new Parameter
{
name = "ClientKey",
#in = "header",
type = "string",
description = "Cliente",
required = true,
#default = "bxbxbx"
});
operation.parameters.Add(new Parameter
{
name = "Authorization",
#in = "header",
type = "apikey",
description = "Token de sesiĆ³n",
});
}
}
I am using .NetCore 3 and Swagger 5.0.0-rc4. I am trying to upload file(image) using Swagger but it does not work because the apply method in the IOperationFilter or even Swashbuckle.AspNetCore.Swagger are missing some attributes. For instance NonBodyParameter and Consumes do not exit in Swagger 5.0
Do anyone use face the same problem or tried to solve it?
public class FileOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.OperationId.ToLower() == "apivaluesuploadpost")
{
operation.Parameters.Clear();
operation.Parameters.Add(new **NonBodyParameter**
{
Name = "uploadedFile",
In = "formData",
Description = "Upload File",
Required = true,
Type = "file"
});
operation.**Consumes**.Add("multipart/form-data");
}
}
}
AS for the missing Parameters Now these are changed to OpenApiParameter and OpenApiOperation.
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.OperationId == "MyOperation")
{
operation.Parameters.Clear();
operation.Parameters.Add(new OpenApiParameter
{
Name = "formFile",
In = ParameterLocation.Header,
Description = "Upload File",
Required = true,
Schema= new OpenApiSchema
{
Type="file",
Format="binary"
}
});
var uploadFileMediaType = new OpenApiMediaType()
{
Schema = new OpenApiSchema()
{
Type = "object",
Properties =
{
["uploadedFile"] = new OpenApiSchema()
{
Description = "Upload File",
Type = "file",
Format = "binary"
}
},
Required = new HashSet<string>()
{
"uploadedFile"
}
}
};
operation.RequestBody = new OpenApiRequestBody
{
Content =
{
["multipart/form-data"] = uploadFileMediaType
}
};
}
}
I managed to solve this in Swashbuckle.AspNetCore 6.1.5
Swagger recognizes automatically IFormFile as a multipart/form-data media type.
You just have to delete the filter class and remove the [FromForm] or [FromBody] attribute from your parameter in the controller.
void Post([FromForm] IFileForm file) <= old
void Post(IFileForm file) <= new
I have implemented a web api with basic authentication filter. When I want to call it from Swagger, I am facing below problems:
1) I am unable to pass the username in Base64 encode.
2) Username is passed in Scheme property of ActionContext.Request.Headers.Authorization instead of Parameter property of the same.
I have tried with below code in swagger.
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.OperationFilter(() => new AddRequiredAuthorizationHeaderParameter());
});
public class AddRequiredAuthorizationHeaderParameter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Instance)
.Any(filter => filter is IAuthorizationFilter);
var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
if (operation.parameters == null)
operation.parameters = new List<Parameter>();
operation.parameters.Add(new Parameter
{
name = "Authorization",
#in = "header",
type = "",
required = true,
description = "User Name"
});
}
}
Please help me out.