Skip to content

Commit

Permalink
Custom attribute routing conventions are supported. Fixes #69.
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Beauchamp committed Feb 15, 2016
1 parent 59db8c0 commit 903a94e
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 7 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>Configuration option now allows Navigation Properties to be included in the entity swagger models.</ReleaseNotes>
<ReleaseNotes>Configuration option now allows Navigation Properties to be included in the entity swagger models. Fixes #69.</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.16.0</Version>
<Version>2.16.1</Version>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Swashbuckle.OData\Swashbuckle.OData.csproj" />
Expand Down
121 changes: 121 additions & 0 deletions Swashbuckle.OData.Tests/Fixtures/CustomRoutingConventionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.OData;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using System.Web.OData.Routing;
using System.Web.OData.Routing.Conventions;
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 CustomRoutingConventionTests
{
[Test]
public async Task It_supports_custom_attribute_routing_convention()
{
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => MillsSetup.Configuration(appBuilder, typeof(MillsSetup.MillsController))))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Verify that the OData route in the test controller is valid
var results = await httpClient.GetJsonAsync<ODataResponse<List<MillsSetup.Mill>>>("odata/Mills");
results.Should().NotBeNull();
results.Value.Count.Should().Be(4);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");

// Assert
PathItem pathItem;
swaggerDocument.paths.TryGetValue("/odata/Mills", out pathItem);
pathItem.Should().NotBeNull();

await ValidationUtils.ValidateSwaggerJson();
}
}
}

public class MillsSetup
{
public static void Configuration(IAppBuilder appBuilder, Type targetController)
{
var config = appBuilder.GetStandardHttpConfig(targetController);

var edmModel = GetEdmModel();

// See http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions
// Create the default collection of built-in conventions.
var conventions = ODataRoutingConventions.CreateDefault();
// Insert the custom convention at the start of the collection.
conventions.Insert(0, new MyAttributeRoutingConvention(edmModel, config));

config.MapODataServiceRoute("ODataRoute", "odata", edmModel, new DefaultODataPathHandler(), conventions);

config.EnsureInitialized();
}

public static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();

builder.EntitySet<Mill>("Mills");

return builder.GetEdmModel();
}

public class Mill
{
[Key]
public long Id { get; set; }
public string Variation { get; set; }
}

public class MillsController : ODataController
{
[EnableQuery]
public IQueryable<Mill> GetMills()
{
var mills = new[]
{
new Mill { Id=1, Variation = "a"},
new Mill { Id=2, Variation = "b"},
new Mill { Id=3, Variation = "c"},
new Mill { Id=4, Variation = "d"}
};

return mills.AsQueryable();
}
}

public class MyAttributeRoutingConvention : AttributeRoutingConvention
{
public MyAttributeRoutingConvention(IEdmModel model, HttpConfiguration configuration) : base(model, configuration)
{
}

public MyAttributeRoutingConvention(IEdmModel model, HttpConfiguration configuration, IODataPathTemplateHandler pathTemplateHandler) : base(model, configuration, pathTemplateHandler)
{
}

public MyAttributeRoutingConvention(IEdmModel model, IEnumerable<HttpControllerDescriptor> controllers) : base(model, controllers)
{
}

public MyAttributeRoutingConvention(IEdmModel model, IEnumerable<HttpControllerDescriptor> controllers, IODataPathTemplateHandler pathTemplateHandler) : base(model, controllers, pathTemplateHandler)
{
}
}
}
}
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 @@ -146,6 +146,7 @@
<Compile Include="ContentType.cs" />
<Compile Include="Fixtures\ParameterTests\DecimalParameterAndResponseTests.cs" />
<Compile Include="Fixtures\ModelSharedBetweenODataAndWebApiTests.cs" />
<Compile Include="Fixtures\CustomRoutingConventionTests.cs" />
<Compile Include="Fixtures\QueryStringParameterTests.cs" />
<Compile Include="Fixtures\ParameterizedRoutePrefixTests.cs" />
<Compile Include="Fixtures\RoutePrefixTests.cs" />
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.16.0")]
[assembly: AssemblyInformationalVersion("2.16.1")]
24 changes: 21 additions & 3 deletions Swashbuckle.OData/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System.Diagnostics.Contracts;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;

namespace Swashbuckle.OData
Expand All @@ -20,14 +23,29 @@ internal static T GetInstanceField<T>(this object instance, string fieldName, bo
Contract.Requires(instance != null);
Contract.Ensures(Contract.Result<T>() != null || !ensureNonNull);

const BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
var fieldInfo = instance.GetType().GetField(fieldName, bindFlags);
var fieldInfo = instance.GetType().GetAllFields().SingleOrDefault(info => info.Name == fieldName);
Contract.Assume(fieldInfo != null);
var value = fieldInfo.GetValue(instance);
Contract.Assume(value != null || !ensureNonNull);
return value != null ? (T)value : default (T);
}

private static IEnumerable<FieldInfo> GetAllFields(this Type type)
{
if (type == null)
{
return Enumerable.Empty<FieldInfo>();
}

const BindingFlags flags = BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Static
| BindingFlags.Instance
| BindingFlags.DeclaredOnly;

return type.GetFields(flags).Concat(GetAllFields(type.BaseType));
}

/// <summary>
/// Uses reflection to set the property value in an object.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 2.16.0.{build}
version: 2.16.1.{build}

before_build:
- cmd: nuget restore
Expand Down

0 comments on commit 903a94e

Please sign in to comment.