diff --git a/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj b/Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
index 6f054dc..dabf1d4 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!
- Support constructor dependency injection. Improve error detection and handling. Fix issue 41.
+ Support constructor dependency injection. Improve error detection and handling. Fixes issues 41, 28.
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.8.4
+ 2.8.5
diff --git a/Swashbuckle.OData.Tests/ODataQueryOptions/ODataQueryOptionsTests.cs b/Swashbuckle.OData.Tests/ODataQueryOptions/ODataQueryOptionsTests.cs
new file mode 100644
index 0000000..0d25cec
--- /dev/null
+++ b/Swashbuckle.OData.Tests/ODataQueryOptions/ODataQueryOptionsTests.cs
@@ -0,0 +1,110 @@
+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 FluentAssertions;
+using Microsoft.OData.Edm;
+using Microsoft.Owin.Hosting;
+using NUnit.Framework;
+using Owin;
+using Swashbuckle.Swagger;
+using System.Web.OData.Query;
+
+namespace Swashbuckle.OData.Tests.ODataQueryOptions
+{
+ [TestFixture]
+ public class ODataQueryOptionsTests
+ {
+ [Test]
+ public async Task It_supports_controller_with_single_get_method_with_odataqueryoptions()
+ {
+ using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(Products3Controller))))
+ {
+ // Arrange
+ var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
+ // Verify that the OData route in the test controller is valid
+ var products = await httpClient.GetJsonAsync>("/odata/Products3");
+ products.Should().NotBeNull();
+ products.Value.Count.Should().Be(100);
+ var product = await httpClient.GetJsonAsync>("/odata/Products3(1)");
+ product.Should().NotBeNull();
+ product.Value.Count.Should().Be(100);
+
+ // Act
+ var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1");
+
+ // Assert
+ PathItem pathItem;
+ swaggerDocument.paths.TryGetValue("/odata/Products3", out pathItem);
+ pathItem.Should().NotBeNull();
+ pathItem.get.Should().NotBeNull();
+
+ PathItem pathItem2;
+ swaggerDocument.paths.TryGetValue("/odata/Products3({Id})", out pathItem2);
+ 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("Products3");
+
+ return builder.GetEdmModel();
+ }
+ }
+
+ public class Product3
+ {
+ [Key]
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public double Price { get; set; }
+ }
+
+ public class Products3Controller : ODataController
+ {
+ private static readonly ConcurrentDictionary Data;
+
+ static Products3Controller()
+ {
+ Data = new ConcurrentDictionary();
+ var rand = new Random();
+
+ Enumerable.Range(0, 100).Select(i => new Product3
+ {
+ Id = i,
+ Name = "Product " + i,
+ Price = rand.NextDouble() * 1000
+ }).ToList().ForEach(p => Data.TryAdd(p.Id, p));
+ }
+
+ [EnableQuery]
+ public Task Get(ODataQueryOptions queryOptions)
+ {
+ var results = (IQueryable)queryOptions.ApplyTo(Data.Values.AsQueryable());
+ return Task.FromResult((IHttpActionResult)Ok(results));
+ }
+ }
+}
\ 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 843e292..11d16a5 100644
--- a/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
+++ b/Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
@@ -168,6 +168,7 @@
+
diff --git a/Swashbuckle.OData/Descriptions/HttpParameterDescriptorExtensions.cs b/Swashbuckle.OData/Descriptions/HttpParameterDescriptorExtensions.cs
new file mode 100644
index 0000000..a30c14c
--- /dev/null
+++ b/Swashbuckle.OData/Descriptions/HttpParameterDescriptorExtensions.cs
@@ -0,0 +1,18 @@
+using System.Diagnostics.Contracts;
+using System.Web.Http.Controllers;
+
+namespace Swashbuckle.OData.Descriptions
+{
+ internal static class HttpParameterDescriptorExtensions
+ {
+ public static bool IsODataQueryOptions(this HttpParameterDescriptor parameterDescriptor)
+ {
+ Contract.Requires(parameterDescriptor != null);
+
+ var parameterType = parameterDescriptor.ParameterType;
+ Contract.Assume(parameterType != null);
+
+ return parameterType.Name == "ODataQueryOptions`1";
+ }
+ }
+}
\ No newline at end of file
diff --git a/Swashbuckle.OData/Descriptions/MapByDescription.cs b/Swashbuckle.OData/Descriptions/MapByDescription.cs
index d7e0327..52da451 100644
--- a/Swashbuckle.OData/Descriptions/MapByDescription.cs
+++ b/Swashbuckle.OData/Descriptions/MapByDescription.cs
@@ -13,7 +13,7 @@ public HttpParameterDescriptor Map(Parameter swaggerParameter, int parameterInde
if (swaggerParameter.description != null && swaggerParameter.description.StartsWith("key:"))
{
var parameterDescriptor = actionDescriptor.GetParameters()?.SingleOrDefault(descriptor => descriptor.ParameterName == "key");
- if (parameterDescriptor != null)
+ if (parameterDescriptor != null && !parameterDescriptor.IsODataQueryOptions())
{
var httpControllerDescriptor = actionDescriptor.ControllerDescriptor;
Contract.Assume(httpControllerDescriptor != null);
diff --git a/Swashbuckle.OData/Descriptions/MapByIndex.cs b/Swashbuckle.OData/Descriptions/MapByIndex.cs
index 87b7f87..bf12a2e 100644
--- a/Swashbuckle.OData/Descriptions/MapByIndex.cs
+++ b/Swashbuckle.OData/Descriptions/MapByIndex.cs
@@ -11,7 +11,7 @@ public HttpParameterDescriptor Map(Parameter swaggerParameter, int parameterInde
if (swaggerParameter.@in != "query" && parameterIndex < actionDescriptor.GetParameters().Count)
{
var parameterDescriptor = actionDescriptor.GetParameters()[parameterIndex];
- if (parameterDescriptor != null)
+ if (parameterDescriptor != null && !parameterDescriptor.IsODataQueryOptions())
{
var httpControllerDescriptor = actionDescriptor.ControllerDescriptor;
Contract.Assume(httpControllerDescriptor != null);
diff --git a/Swashbuckle.OData/Properties/AssemblyInfo.cs b/Swashbuckle.OData/Properties/AssemblyInfo.cs
index 2431d2f..a3cfb00 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.8.4")]
\ No newline at end of file
+[assembly: AssemblyInformationalVersion("2.8.5")]
\ No newline at end of file
diff --git a/Swashbuckle.OData/Swashbuckle.OData.csproj b/Swashbuckle.OData/Swashbuckle.OData.csproj
index 357a289..a73ac57 100644
--- a/Swashbuckle.OData/Swashbuckle.OData.csproj
+++ b/Swashbuckle.OData/Swashbuckle.OData.csproj
@@ -174,6 +174,7 @@
+