diff --git a/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj b/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
index afbcab2..151e821 100644
--- a/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
+++ b/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
@@ -25,12 +25,12 @@
Richard Beauchamp
Extends Swashbuckle with OData v4 support!
Extends Swashbuckle with OData v4 support!
- Provide single quotes around swagger path parameters of type string
+ Supports OData paths that contain parameters of type array
https://github.com/rbeauchamp/Swashbuckle.OData
https://github.com/rbeauchamp/Swashbuckle.OData/blob/master/License.txt
Copyright 2015
Swashbuckle Swagger SwaggerUi OData Documentation Discovery Help WebApi AspNet AspNetWebApi Docs WebHost IIS
- 2.7.1
+ 2.7.2
diff --git a/Swashbuckle.OData.Sample/App_Start/ODataConfig.cs b/Swashbuckle.OData.Sample/App_Start/ODataConfig.cs
index f25f8be..c0d2d7d 100644
--- a/Swashbuckle.OData.Sample/App_Start/ODataConfig.cs
+++ b/Swashbuckle.OData.Sample/App_Start/ODataConfig.cs
@@ -98,13 +98,13 @@ private static IEdmModel GetFunctionsEdmModel()
var productType = builder.EntityType();
- // Function bound to a collection
+ // Function bound to an entity set
// Returns the most expensive product, a single entity
productType.Collection
.Function("MostExpensive")
.Returns();
- // Function bound to a collection
+ // Function bound to an entity set
// Returns the top 10 product, a collection
productType.Collection
.Function("Top10")
@@ -125,12 +125,12 @@ private static IEdmModel GetFunctionsEdmModel()
.Returns()
.Parameter("state");
- // Commented out because unbound functions don't
- // play well in a config with mulitple OData routes
- // Unbound Function
- //builder.Function("GetSalesTaxRate")
- // .Returns()
- // .Parameter("state");
+ // Function bound to an entity set
+ // Accepts an array as a parameter
+ productType.Collection
+ .Function("ProductsWithIds")
+ .ReturnsCollectionFromEntitySet("Products")
+ .CollectionParameter("Ids");
return builder.GetEdmModel();
}
diff --git a/Swashbuckle.OData.Sample/ODataControllers/CustomersController.cs b/Swashbuckle.OData.Sample/ODataControllers/CustomersController.cs
index bb1a0d0..cd39c57 100644
--- a/Swashbuckle.OData.Sample/ODataControllers/CustomersController.cs
+++ b/Swashbuckle.OData.Sample/ODataControllers/CustomersController.cs
@@ -5,7 +5,6 @@
using System.Web.Http;
using System.Web.Http.Description;
using System.Web.OData;
-using System.Web.OData.Routing;
using SwashbuckleODataSample.Models;
using SwashbuckleODataSample.Repositories;
diff --git a/Swashbuckle.OData.Sample/ODataControllers/ProductsController.cs b/Swashbuckle.OData.Sample/ODataControllers/ProductsController.cs
index 077bc12..b966b4c 100644
--- a/Swashbuckle.OData.Sample/ODataControllers/ProductsController.cs
+++ b/Swashbuckle.OData.Sample/ODataControllers/ProductsController.cs
@@ -80,7 +80,7 @@ public IHttpActionResult GetPriceRank(int key)
}
///
- /// Get the sales tax for a product in a given state. This is a function which accepts a parameter.
+ /// Get the sales tax for a product in a given state. This function accepts a parameter.
///
/// The product id
/// The state
@@ -99,17 +99,16 @@ public IHttpActionResult CalculateGeneralSalesTax(int key, string state)
return NotFound();
}
- /////
- ///// Get the sales tax rate for a state. This is an unbound function.
- /////
- ///// The state
- //[HttpGet]
- //[ResponseType(typeof(double))]
- //[ODataRoute("GetSalesTaxRate(state={state})")]
- //public IHttpActionResult GetSalesTaxRate([FromODataUri] string state)
- //{
- // return Ok(GetRate(state));
- //}
+ ///
+ /// Get products with the given Ids. This function accepts a parameter of type 'array'.
+ ///
+ /// The ids.
+ ///
+ [HttpGet]
+ public IQueryable ProductsWithIds([FromODataUri]int[] Ids)
+ {
+ return Data.Values.Where(p => Ids.Contains(p.Id)).AsQueryable();
+ }
private static double GetRate(string state)
{
diff --git a/Swashbuckle.OData.Tests/Containment/ContainmentTests.cs b/Swashbuckle.OData.Tests/Containment/ContainmentTests.cs
index c565f14..f3c0b51 100644
--- a/Swashbuckle.OData.Tests/Containment/ContainmentTests.cs
+++ b/Swashbuckle.OData.Tests/Containment/ContainmentTests.cs
@@ -6,7 +6,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
namespace Swashbuckle.OData.Tests.Containment
{
@@ -19,7 +18,7 @@ public async Task It_supports_models_that_use_containment()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(AccountsController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -39,7 +38,7 @@ public async Task It_supports_odata_attribute_routing()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(AccountsController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/CustomRouteTests.cs b/Swashbuckle.OData.Tests/Fixtures/CustomRouteTests.cs
index 7c96eb1..6104708 100644
--- a/Swashbuckle.OData.Tests/Fixtures/CustomRouteTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/CustomRouteTests.cs
@@ -26,7 +26,7 @@ public async Task It_allows_definition_of_custom_routes()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder, typeof(OrdersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/FromUriArrayTests.cs b/Swashbuckle.OData.Tests/Fixtures/FromUriArrayTests.cs
new file mode 100644
index 0000000..9c83a4e
--- /dev/null
+++ b/Swashbuckle.OData.Tests/Fixtures/FromUriArrayTests.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Concurrent;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Web.Http;
+using System.Web.OData;
+using System.Web.OData.Builder;
+using System.Web.OData.Extensions;
+using System.Web.OData.Routing;
+using FluentAssertions;
+using Microsoft.OData.Edm;
+using Microsoft.Owin.Hosting;
+using NUnit.Framework;
+using Owin;
+using Swashbuckle.Swagger;
+
+namespace Swashbuckle.OData.Tests
+{
+ [TestFixture]
+ public class FromUriArrayTests
+ {
+ [Test]
+ public async Task It_supports_uris_that_contain_arrays()
+ {
+ using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(Products2Controller))))
+ {
+ // Arrange
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
+ // Verify that the OData route is valid
+ var products = await httpClient.GetJsonAsync>("/odata/ProductsWithIds(Ids=[0,1])");
+ products.Should().NotBeNull();
+ products.Value.Count.Should().Be(2);
+
+ // Act
+ var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
+
+ // Assert
+ PathItem pathItem;
+ swaggerDocument.paths.TryGetValue("/odata/ProductsWithIds(Ids=[{Ids}])", out pathItem);
+ pathItem.Should().NotBeNull();
+ pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
+ }
+ }
+
+ private static void Configuration(IAppBuilder appBuilder, Type targetController)
+ {
+ var config = appBuilder.GetStandardHttpConfig(targetController);
+
+ // Define a route to a controller class that contains functions
+ config.MapODataServiceRoute("FromUriArrayRoute", "odata", GetEdmModel());
+
+ config.EnsureInitialized();
+ }
+
+ private static IEdmModel GetEdmModel()
+ {
+ ODataModelBuilder builder = new ODataConventionModelBuilder();
+
+ builder.EntitySet("Products");
+
+ builder.Function("ProductsWithIds")
+ .ReturnsCollectionFromEntitySet("Products")
+ .CollectionParameter("Ids");
+
+ return builder.GetEdmModel();
+ }
+ }
+
+ public class Product2
+ {
+ [Key]
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public double Price { get; set; }
+ }
+
+ public class Products2Controller : ODataController
+ {
+ private static readonly ConcurrentDictionary Data;
+
+ static Products2Controller()
+ {
+ Data = new ConcurrentDictionary();
+ var rand = new Random();
+
+ Enumerable.Range(0, 100).Select(i => new Product2
+ {
+ Id = i,
+ Name = "Product " + i,
+ Price = rand.NextDouble() * 1000
+ }).ToList().ForEach(p => Data.TryAdd(p.Id, p));
+ }
+
+ [HttpGet]
+ [ODataRoute("ProductsWithIds(Ids={Ids})")]
+ public IQueryable ProductsWithIds([FromODataUri]int[] Ids)
+ {
+ return Data.Values.Where(p => Ids.Contains(p.Id)).AsQueryable();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Swashbuckle.OData.Tests/Fixtures/FunctionTests.cs b/Swashbuckle.OData.Tests/Fixtures/FunctionTests.cs
index db10600..c6800d2 100644
--- a/Swashbuckle.OData.Tests/Fixtures/FunctionTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/FunctionTests.cs
@@ -16,7 +16,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
namespace Swashbuckle.OData.Tests
@@ -30,7 +29,7 @@ public async Task It_supports_a_parameterless_function_bound_to_a_collection()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -40,6 +39,8 @@ public async Task It_supports_a_parameterless_function_bound_to_a_collection()
swaggerDocument.paths.TryGetValue("/odata/v1/Products/Default.MostExpensive()", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
}
}
@@ -49,7 +50,7 @@ public async Task It_supports_a_function_bound_to_an_entity_set_that_returns_a_c
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -59,6 +60,8 @@ public async Task It_supports_a_function_bound_to_an_entity_set_that_returns_a_c
swaggerDocument.paths.TryGetValue("/odata/v1/Products/Default.Top10()", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
}
}
@@ -68,7 +71,7 @@ public async Task It_supports_a_function_bound_to_an_entity()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -78,6 +81,8 @@ public async Task It_supports_a_function_bound_to_an_entity()
swaggerDocument.paths.TryGetValue("/odata/v1/Products({Id})/Default.GetPriceRank()", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
}
}
@@ -87,7 +92,7 @@ public async Task It_supports_a_function_that_accepts_a_string_parameter()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -97,6 +102,8 @@ public async Task It_supports_a_function_that_accepts_a_string_parameter()
swaggerDocument.paths.TryGetValue("/odata/v1/Products({Id})/Default.CalculateGeneralSalesTax(state='{state}')", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
}
}
@@ -106,7 +113,7 @@ public async Task It_supports_unbound_functions()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -116,6 +123,8 @@ public async Task It_supports_unbound_functions()
swaggerDocument.paths.TryGetValue("/odata/v1/GetSalesTaxRate(state='{state}')", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();
+
+ await ValidationUtils.ValidateSwaggerJson();
}
}
diff --git a/Swashbuckle.OData.Tests/Fixtures/GetTests.cs b/Swashbuckle.OData.Tests/Fixtures/GetTests.cs
index 283f589..9914e44 100644
--- a/Swashbuckle.OData.Tests/Fixtures/GetTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/GetTests.cs
@@ -9,7 +9,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
using SwashbuckleODataSample.ODataControllers;
@@ -24,7 +23,7 @@ public async Task It_includes_the_filter_parameter()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -49,7 +48,7 @@ public async Task It_has_all_optional_odata_query_parameters()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -69,7 +68,7 @@ public async Task It_has_a_parameter_with_a_name_equal_to_the_path_name()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -91,7 +90,7 @@ public async Task It_supports_types_with_a_guid_primary_key()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(OrdersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/ODataSwaggerProviderTests.cs b/Swashbuckle.OData.Tests/Fixtures/ODataSwaggerProviderTests.cs
index 2069476..9dc6c4a 100644
--- a/Swashbuckle.OData.Tests/Fixtures/ODataSwaggerProviderTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/ODataSwaggerProviderTests.cs
@@ -25,7 +25,7 @@ public async Task It_applies_document_filters()
{
// Arrange
Action config = c => c.DocumentFilter();
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder, unitTestConfigs: config)))
{
@@ -45,7 +45,7 @@ public async Task It_supports_multiple_odata_routes()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder)))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -63,7 +63,7 @@ public async Task It_supports_odata_routes_that_dont_map_to_a_controller()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder)))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -81,7 +81,7 @@ public async Task It_explores_the_correct_controller()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -102,7 +102,7 @@ public async Task It_explores_the_correct_versioned_controller()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder, typeof(CustomersV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -123,7 +123,7 @@ public async Task It_supports_both_webapi_and_odata_controllers()
using (WebApp.Start(HttpClientUtils.BaseAddress, builder => Configuration(builder, typeof(ClientsController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/PatchTests.cs b/Swashbuckle.OData.Tests/Fixtures/PatchTests.cs
index a461c78..667a969 100644
--- a/Swashbuckle.OData.Tests/Fixtures/PatchTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/PatchTests.cs
@@ -9,7 +9,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
using SwashbuckleODataSample.ODataControllers;
@@ -24,7 +23,7 @@ public async Task It_has_a_body_parameter_with_a_schema()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(OrdersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/PostTests.cs b/Swashbuckle.OData.Tests/Fixtures/PostTests.cs
index a771998..b0d12a4 100644
--- a/Swashbuckle.OData.Tests/Fixtures/PostTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/PostTests.cs
@@ -8,7 +8,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
using SwashbuckleODataSample.ODataControllers;
@@ -23,7 +22,7 @@ public async Task It_has_a_summary()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/PutTests.cs b/Swashbuckle.OData.Tests/Fixtures/PutTests.cs
index b7b542c..b67b916 100644
--- a/Swashbuckle.OData.Tests/Fixtures/PutTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/PutTests.cs
@@ -8,7 +8,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
using SwashbuckleODataSample.ODataControllers;
@@ -23,7 +22,7 @@ public async Task It_includes_a_put_operation()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -44,7 +43,7 @@ public async Task It_does_not_exist_if_not_in_the_controller()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(OrdersController))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/RestierTests.cs b/Swashbuckle.OData.Tests/Fixtures/RestierTests.cs
index ab7281f..a712502 100644
--- a/Swashbuckle.OData.Tests/Fixtures/RestierTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/RestierTests.cs
@@ -32,7 +32,7 @@ public async Task It_supports_restier()
using (WebApp.Start(HttpClientUtils.BaseAddress, Configuration))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -54,7 +54,7 @@ public async Task It_has_a_restier_get_with_all_optional_query_parameters()
using (WebApp.Start(HttpClientUtils.BaseAddress, Configuration))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -74,7 +74,7 @@ public async Task It_has_a_restier_response_with_the_correct_edm_model_type()
using (WebApp.Start(HttpClientUtils.BaseAddress, Configuration))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -96,7 +96,7 @@ public async Task It_groups_paths_by_entity_set()
using (WebApp.Start(HttpClientUtils.BaseAddress, Configuration))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
@@ -116,7 +116,7 @@ public async Task It_has_a_restier_get_users_response_of_type_array()
using (WebApp.Start(HttpClientUtils.BaseAddress, Configuration))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/Fixtures/StringTypeUrlParamTests.cs b/Swashbuckle.OData.Tests/Fixtures/StringTypeUrlParamTests.cs
index 8ad60ec..4c93637 100644
--- a/Swashbuckle.OData.Tests/Fixtures/StringTypeUrlParamTests.cs
+++ b/Swashbuckle.OData.Tests/Fixtures/StringTypeUrlParamTests.cs
@@ -9,7 +9,6 @@
using NUnit.Framework;
using Owin;
using Swashbuckle.Swagger;
-using SwashbuckleODataSample;
using SwashbuckleODataSample.Models;
namespace Swashbuckle.OData.Tests
@@ -23,7 +22,7 @@ public async Task It_wraps_string_type_url_params_with_single_quotes()
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller))))
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData.Tests/HttpClientUtils.cs b/Swashbuckle.OData.Tests/HttpClientUtils.cs
index b8ba7e5..759ff91 100644
--- a/Swashbuckle.OData.Tests/HttpClientUtils.cs
+++ b/Swashbuckle.OData.Tests/HttpClientUtils.cs
@@ -1,7 +1,6 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
-using Flurl;
namespace Swashbuckle.OData.Tests
{
@@ -9,11 +8,11 @@ public class HttpClientUtils
{
public const string BaseAddress = "http://localhost:8347/";
- public static HttpClient GetHttpClient(string baseAddress, string routePrefix = null)
+ public static HttpClient GetHttpClient(string baseAddress)
{
var client = new HttpClient
{
- BaseAddress = string.IsNullOrWhiteSpace(routePrefix) ? new Uri(baseAddress) : new Uri(baseAddress.AppendPathSegment(routePrefix)),
+ BaseAddress = new Uri(baseAddress),
Timeout = TimeSpan.FromMilliseconds(5 * 60 * 1000)
};
diff --git a/Swashbuckle.OData.Tests/ODataResponse.cs b/Swashbuckle.OData.Tests/ODataResponse.cs
new file mode 100644
index 0000000..32da0ef
--- /dev/null
+++ b/Swashbuckle.OData.Tests/ODataResponse.cs
@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace Swashbuckle.OData.Tests
+{
+ internal class ODataResponse
+ {
+ public List Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj b/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
index c97a0db..bfa506f 100644
--- a/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
+++ b/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
@@ -143,6 +143,7 @@
+
@@ -165,6 +166,7 @@
+
diff --git a/Swashbuckle.OData.Tests/ValidationUtils.cs b/Swashbuckle.OData.Tests/ValidationUtils.cs
index f7e2a04..12ee1fe 100644
--- a/Swashbuckle.OData.Tests/ValidationUtils.cs
+++ b/Swashbuckle.OData.Tests/ValidationUtils.cs
@@ -5,7 +5,6 @@
using FluentAssertions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
-using SwashbuckleODataSample;
namespace Swashbuckle.OData.Tests
{
@@ -14,7 +13,7 @@ public static class ValidationUtils
public static async Task ValidateSwaggerJson()
{
// Arrange
- var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress, ODataConfig.ODataRoutePrefix);
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Act
var response = await httpClient.GetAsync("swagger/docs/v1");
diff --git a/Swashbuckle.OData/Descriptions/ApiDescriptionExtensions.cs b/Swashbuckle.OData/Descriptions/ApiDescriptionExtensions.cs
index bee9491..a55674f 100644
--- a/Swashbuckle.OData/Descriptions/ApiDescriptionExtensions.cs
+++ b/Swashbuckle.OData/Descriptions/ApiDescriptionExtensions.cs
@@ -1,25 +1,49 @@
-using System.Web.Http.Description;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Web.Http.Description;
using Swashbuckle.Swagger;
namespace Swashbuckle.OData.Descriptions
{
public static class ApiDescriptionExtensions
{
- public static string GetRelativePathWithQuotedStringParams(this ApiDescription apiDescription)
+ public static string GetRelativePathForSwagger(this ApiDescription apiDescription)
{
var parameters = apiDescription.ParameterDescriptions;
var newRelativePathSansQueryString = apiDescription.RelativePathSansQueryString();
+ newRelativePathSansQueryString = AdjustRelativePathForStringParams(parameters, newRelativePathSansQueryString);
+ newRelativePathSansQueryString = AdjustRelativePathForArrayParams(parameters, newRelativePathSansQueryString);
+
+ return apiDescription.RelativePath.Replace(apiDescription.RelativePathSansQueryString(), newRelativePathSansQueryString);
+ }
+
+ private static string AdjustRelativePathForStringParams(IEnumerable parameters, string newRelativePathSansQueryString)
+ {
foreach (var parameter in parameters)
{
- if (newRelativePathSansQueryString.Contains("{" + parameter.Name + "}") && parameter.ParameterDescriptor.ParameterType == typeof(string))
+ if (newRelativePathSansQueryString.Contains("{" + parameter.Name + "}") && parameter.ParameterDescriptor.ParameterType == typeof (string))
{
newRelativePathSansQueryString = newRelativePathSansQueryString.Replace("{" + parameter.Name + "}", "\'{" + parameter.Name + "}\'");
}
}
+ return newRelativePathSansQueryString;
+ }
- return apiDescription.RelativePath.Replace(apiDescription.RelativePathSansQueryString(), newRelativePathSansQueryString);
+ private static string AdjustRelativePathForArrayParams(IEnumerable parameters, string newRelativePathSansQueryString)
+ {
+ foreach (var parameter in parameters)
+ {
+ if (newRelativePathSansQueryString.Contains("{" + parameter.Name + "}")
+ && typeof(IEnumerable).IsAssignableFrom(parameter.ParameterDescriptor.ParameterType)
+ && parameter.ParameterDescriptor.ParameterType != typeof(string))
+ {
+ newRelativePathSansQueryString = newRelativePathSansQueryString.Replace("{" + parameter.Name + "}", "[{" + parameter.Name + "}]");
+ }
+ }
+ return newRelativePathSansQueryString;
}
}
}
\ No newline at end of file
diff --git a/Swashbuckle.OData/Descriptions/ODataActionDescriptorMapper.cs b/Swashbuckle.OData/Descriptions/ODataActionDescriptorMapper.cs
index 92aa179..070d329 100644
--- a/Swashbuckle.OData/Descriptions/ODataActionDescriptorMapper.cs
+++ b/Swashbuckle.OData/Descriptions/ODataActionDescriptorMapper.cs
@@ -63,7 +63,7 @@ public IEnumerable Map(ODataActionDescriptor oDataActionDescript
// Have to set ResponseDescription because it's internal!??
apiDescription.GetType().GetProperty("ResponseDescription").SetValue(apiDescription, responseDescription);
- apiDescription.RelativePath = apiDescription.GetRelativePathWithQuotedStringParams();
+ apiDescription.RelativePath = apiDescription.GetRelativePathForSwagger();
apiDescriptions.Add(apiDescription);
}
diff --git a/Swashbuckle.OData/Descriptions/ParameterExtensions.cs b/Swashbuckle.OData/Descriptions/ParameterExtensions.cs
index 96e01a9..db0bcf2 100644
--- a/Swashbuckle.OData/Descriptions/ParameterExtensions.cs
+++ b/Swashbuckle.OData/Descriptions/ParameterExtensions.cs
@@ -89,6 +89,8 @@ public static string GenerateSamplePathParameterValue(this Parameter parameter)
return "\'SampleString\'";
case "boolean":
return "true";
+ case "array":
+ return "[]";
default:
throw new Exception($"Could not generate sample value for query parameter type {type} and format {"null"}");
}
diff --git a/Swashbuckle.OData/Descriptions/SwaggerOperationMapper.cs b/Swashbuckle.OData/Descriptions/SwaggerOperationMapper.cs
index f2a5335..3a0e960 100644
--- a/Swashbuckle.OData/Descriptions/SwaggerOperationMapper.cs
+++ b/Swashbuckle.OData/Descriptions/SwaggerOperationMapper.cs
@@ -67,7 +67,7 @@ public IEnumerable Map(ODataActionDescriptor oDataActionDescript
// Have to set ResponseDescription because it's internal!??
apiDescription.GetType().GetProperty("ResponseDescription").SetValue(apiDescription, responseDescription);
- apiDescription.RelativePath = apiDescription.GetRelativePathWithQuotedStringParams();
+ apiDescription.RelativePath = apiDescription.GetRelativePathForSwagger();
apiDescriptions.Add(apiDescription);
}
diff --git a/Swashbuckle.OData/Properties/AssemblyInfo.cs b/Swashbuckle.OData/Properties/AssemblyInfo.cs
index a0188dc..20e35af 100644
--- a/Swashbuckle.OData/Properties/AssemblyInfo.cs
+++ b/Swashbuckle.OData/Properties/AssemblyInfo.cs
@@ -37,4 +37,4 @@
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
-[assembly: AssemblyInformationalVersion("2.7.1")]
\ No newline at end of file
+[assembly: AssemblyInformationalVersion("2.7.2")]
\ No newline at end of file