Skip to content

Commit

Permalink
Don't map OData path parameters to ODataQueryOptions. Fixes #28.
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Beauchamp committed Dec 30, 2015
1 parent a139e32 commit 62f164c
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 5 deletions.
4 changes: 2 additions & 2 deletions Swashbuckle.OData.Nuget/Swashbuckle.OData.NuGet.nuproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
<Owners>Richard Beauchamp</Owners>
<Summary>Extends Swashbuckle with OData v4 support!</Summary>
<Description>Extends Swashbuckle with OData v4 support!</Description>
<ReleaseNotes>Support constructor dependency injection. Improve error detection and handling. Fix issue 41.</ReleaseNotes>
<ReleaseNotes>Support constructor dependency injection. Improve error detection and handling. Fixes issues 41, 28.</ReleaseNotes>
<ProjectUrl>https://github.com/rbeauchamp/Swashbuckle.OData</ProjectUrl>
<LicenseUrl>https://github.com/rbeauchamp/Swashbuckle.OData/blob/master/License.txt</LicenseUrl>
<Copyright>Copyright 2015</Copyright>
<Tags>Swashbuckle Swagger SwaggerUi OData Documentation Discovery Help WebApi AspNet AspNetWebApi Docs WebHost IIS</Tags>
<Version>2.8.4</Version>
<Version>2.8.5</Version>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Swashbuckle.OData\Swashbuckle.OData.csproj" />
Expand Down
110 changes: 110 additions & 0 deletions Swashbuckle.OData.Tests/ODataQueryOptions/ODataQueryOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -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<ODataResponse<Product3>>("/odata/Products3");
products.Should().NotBeNull();
products.Value.Count.Should().Be(100);
var product = await httpClient.GetJsonAsync<ODataResponse<Product3>>("/odata/Products3(1)");
product.Should().NotBeNull();
product.Value.Count.Should().Be(100);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("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<Product3>("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<int, Product3> Data;

static Products3Controller()
{
Data = new ConcurrentDictionary<int, Product3>();
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<IHttpActionResult> Get(ODataQueryOptions<Product3> queryOptions)
{
var results = (IQueryable<Product3>)queryOptions.ApplyTo(Data.Values.AsQueryable());
return Task.FromResult((IHttpActionResult)Ok(results));
}
}
}
1 change: 1 addition & 0 deletions Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
<Compile Include="NorthwindAPI\Shipper.cs" />
<Compile Include="NorthwindAPI\Supplier.cs" />
<Compile Include="NorthwindAPI\Territory.cs" />
<Compile Include="ODataQueryOptions\ODataQueryOptionsTests.cs" />
<Compile Include="ODataResponse.cs" />
<Compile Include="ODataVersionControllerSelector.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
}
}
}
2 changes: 1 addition & 1 deletion Swashbuckle.OData/Descriptions/MapByDescription.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Swashbuckle.OData/Descriptions/MapByIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion Swashbuckle.OData/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("2.8.4")]
[assembly: AssemblyInformationalVersion("2.8.5")]
1 change: 1 addition & 0 deletions Swashbuckle.OData/Swashbuckle.OData.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
<Compile Include="DefaultCompositionRoot.cs" />
<Compile Include="Descriptions\ApiDescriptionExtensions.cs" />
<Compile Include="Descriptions\AttributeRouteStrategy.cs" />
<Compile Include="Descriptions\HttpParameterDescriptorExtensions.cs" />
<Compile Include="Descriptions\IODataActionDescriptorMapper.cs" />
<Compile Include="Descriptions\IODataActionDescriptorExplorer.cs" />
<Compile Include="Descriptions\ODataActionDescriptor.cs" />
Expand Down

0 comments on commit 62f164c

Please sign in to comment.