📣 Calling for Maintainers |
---|
Because OData WebApi does not support ASP.NET Core (see OData/WebApi#939) and I am 100% focused on new ASP.NET Core development, I don't have the capacity to maintain this project. Still, I'd love to see it live on and am seeking one or two "core" contributors / maintainers. Ideally, these would be people who have already contributed through PRs and understand the inner workings and overall design. If you're interested, please let me know by adding a comment here. Thank you! |
Extends Swashbuckle with OData v4 support! Supports both WebApi and OData controllers!
Install Swashbuckle
Install the Swashbuckle.OData NuGet package:
Install-Package Swashbuckle.OData
In SwaggerConfig
configure the custom provider:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration));
By default, OData does not get related entities unless you specify $expand
on a navigation property.
Swashbuckle.OData tries to accurately reflect this behavior and therefore, by default, does not include
navigation properties in your entity swagger models. You can override this though by specifying:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration).Configure(odataConfig =>
{
odataConfig.IncludeNavigationProperties();
}));
To enable the built-in cache functionality you must set this configuration:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration).Configure(odataConfig =>
{
// Enable Cache for swagger doc requests
odataConfig.EnableSwaggerRequestCaching();
}));
Configuration example to inject your own IAssembliesResolver instead of using DefaultAssembliesResolver:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration).Configure(odataConfig =>
{
//Set custom AssembliesResolver
odataConfig.SetAssembliesResolver(new CustomAssembliesResolver());
}));
The following snippet demonstrates how to configure a custom swagger route such that it will appear in the Swagger UI:
// Let's say you map a custom OData route that doesn't follow the OData conventions
// and where the target controller action doesn't have an [ODataRoute] attribute
var customODataRoute = config.MapODataServiceRoute("CustomODataRoute", ODataRoutePrefix, GetModel(), batchHandler: null, pathHandler: new DefaultODataPathHandler(), routingConventions: myCustomConventions);
// Then describe your route to Swashbuckle.OData so that it will appear in the Swagger UI
config.AddCustomSwaggerRoute(customODataRoute, "/Customers({Id})/Orders")
.Operation(HttpMethod.Post)
// The name of the parameter as it appears in the path
.PathParameter<int>("Id")
// The name of the parameter as it appears in the controller action
.BodyParameter<Order>("order");
The above route resolves to an OrdersController
(the last path segment defining the controller) and hits the Post
action:
[ResponseType(typeof(Order))]
public async Task<IHttpActionResult> Post([FromODataUri] int customerId, Order order)
{
...
}
The following snippet demonstrates how to configure a custom property resolver, which resolves a schema's property name, instead of using a DataMemberAttribute:
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, GlobalConfiguration.Configuration).Configure(odataConfig =>
{
//Set custom ProperyResolver
odataConfig.SetProperyResolver(new DefaultProperyResolver());
}));
By default, Swashbuckle.OData only displays RESTier routes for top-level entity types. You can describe and display additional routes, for related types, in the Swagger UI by configuring custom swagger routes. For example from the Northwind model, to display a route that queries an Order (a related type) for a Customer (a top-level entity type), configure the following:
var restierRoute = await config.MapRestierRoute<DbApi<NorthwindContext>>("RESTierRoute", "restier", new RestierBatchHandler(server));
config.AddCustomSwaggerRoute(restierRoute, "/Customers({CustomerId})/Orders({OrderId})")
.Operation(HttpMethod.Get)
.PathParameter<string>("CustomerId")
.PathParameter<int>("OrderId");
The follow snippet demonstrates how to configure route prefixes that have parameters:
// For example, if you have a route prefix with a parameter "tenantId" of type long
var odataRoute = config.MapODataServiceRoute("odata", "odata/{tenantId}", builder.GetEdmModel());
// Then add the following route constraint so that Swashbuckle.OData knows the parameter type.
// If you don't add this line then the parameter will be assumed to be of type string.
odataRoute.Constraints.Add("tenantId", new LongRouteConstraint());
Swashbuckle.OData supports the following route constraints:
Parameter Type | Route Constraint |
---|---|
bool |
BoolRouteConstraint |
DateTime |
DateTimeRouteConstraint |
decimal |
DecimalRouteConstraint |
double |
DoubleRouteConstraint |
float |
FloatRouteConstraint |
Guid |
GuidRouteConstraint |
int |
IntRouteConstraint |
long |
LongRouteConstraint |
If your service is hosted using OWIN middleware, configure the custom provider as follows:
httpConfiguration
.EnableSwagger(c =>
{
// Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to
// hold additional metadata for an API. Version and title are required but you can also provide
// additional fields by chaining methods off SingleApiVersion.
//
c.SingleApiVersion("v1", "A title for your API");
// Wrap the default SwaggerGenerator with additional behavior (e.g. caching) or provide an
// alternative implementation for ISwaggerProvider with the CustomProvider option.
//
c.CustomProvider(defaultProvider => new ODataSwaggerProvider(defaultProvider, c, httpConfiguration));
})
.EnableSwaggerUi();
You'll need:
- Visual Studio 2015
- Code Contracts
- NuGet Package Project to generate the NuGet package.
If you submit an enhancement or bug fix, please include a unit test similar to this that verifies the change. Let's shoot for 100% unit test coverage of the code base.