Skip to content

Commit

Permalink
Displayed model schema property names now match EdmModel property nam…
Browse files Browse the repository at this point in the history
…es. Fixes #59.
  • Loading branch information
Richard Beauchamp committed Jan 27, 2016
1 parent d355430 commit 3d277c7
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 28 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>Provides explicit, unit tested support for OData actions.</ReleaseNotes>
<ReleaseNotes>Provides explicit, unit tested support for OData actions. Fixes #59.</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.12.0</Version>
<Version>2.12.1</Version>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Swashbuckle.OData\Swashbuckle.OData.csproj" />
Expand Down
2 changes: 2 additions & 0 deletions Swashbuckle.OData.Sample/App_Start/FormatterConfig.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Web.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace SwashbuckleODataSample
{
Expand All @@ -18,6 +19,7 @@ public static void Register(HttpConfiguration config)

formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
Expand Down
15 changes: 14 additions & 1 deletion Swashbuckle.OData.Sample/App_Start/ODataConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,49 @@ private static void ConfigureWebApiOData(HttpConfiguration config)
private static IEdmModel GetDefaultModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntitySet<Customer>("Customers");
builder.EntitySet<Order>("Orders");

return builder.GetEdmModel();
}

private static IEdmModel GetCustomRouteModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntitySet<Customer>("Customers");
builder.EntitySet<Order>("Orders");

return builder.GetEdmModel();
}

private static IEdmModel GetVersionedModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntitySet<Customer>("Customers");

return builder.GetEdmModel();
}

private static IEdmModel GetFakeModel()
{
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntitySet<Customer>("FakeCustomers");

return builder.GetEdmModel();
}

private static IEdmModel GetFunctionsEdmModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntitySet<Product>("Products");

Expand Down
89 changes: 89 additions & 0 deletions Swashbuckle.OData.Tests/Fixtures/ModelSchemaTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.Serialization;
using System.Threading.Tasks;
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;

namespace Swashbuckle.OData.Tests
{
[TestFixture]
public class ModelSchemaTests
{
[Test]
public async Task The_model_schema_matches_the_edm_model()
{
using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(BrandsController))))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);
// Verify that the OData route in the test controller is valid
var result = await httpClient.GetAsync("/odata/Brands");
result.IsSuccessStatusCode.Should().BeTrue();

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

// Assert
swaggerDocument.definitions.Should().ContainKey("Brand");
var brandSchema = swaggerDocument.definitions["Brand"];

brandSchema.properties.Should().ContainKey("id");
brandSchema.properties.Should().ContainKey("code");
brandSchema.properties.Should().ContainKey("name");
brandSchema.properties.Should().ContainKey("Something");

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("ODataRoute", "odata", GetEdmModel());

config.EnsureInitialized();
}

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

builder.EntitySet<Brand>("Brands");

builder.EnableLowerCamelCase(NameResolverOptions.ProcessReflectedPropertyNames | NameResolverOptions.ProcessExplicitPropertyNames);

return builder.GetEdmModel();
}
}

public class Brand
{
[Key]
public long Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }

[DataMember(Name = "Something")]
public string Description { get; set; }
}

public class BrandsController : ODataController
{
[EnableQuery]
public IQueryable<Brand> GetBrands()
{
return Enumerable.Empty<Brand>().AsQueryable();
}
}
}
2 changes: 1 addition & 1 deletion Swashbuckle.OData.Tests/Fixtures/SchemaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public async Task Schema_contains_nested_reference_types_for_web_api_controllers
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");

// Assert
swaggerDocument.definitions["Client"].properties.ContainsKey("Projects").Should().BeTrue();
swaggerDocument.definitions["Client"].properties.ContainsKey("projects").Should().BeTrue();

await ValidationUtils.ValidateSwaggerJson();
}
Expand Down
2 changes: 2 additions & 0 deletions Swashbuckle.OData.Tests/Swashbuckle.OData.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
<Private>True</Private>
Expand All @@ -143,6 +144,7 @@
<Compile Include="Containment\ODataModels.cs" />
<Compile Include="Containment\Program.cs" />
<Compile Include="ContentType.cs" />
<Compile Include="Fixtures\ModelSchemaTests.cs" />
<Compile Include="Fixtures\CustomSwaggerRouteTests.cs" />
<Compile Include="Fixtures\EnableQueryTests.cs" />
<Compile Include="Fixtures\FromUriArrayTests.cs" />
Expand Down
23 changes: 13 additions & 10 deletions Swashbuckle.OData/ODataSwaggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.ServiceModel.Description;
using System.Web.Http;
using System.Web.Http.Description;
using System.Web.OData.Routing;
using Microsoft.OData.Edm;
using Swashbuckle.Application;
using Swashbuckle.OData.Descriptions;
using Swashbuckle.Swagger;
Expand Down Expand Up @@ -90,7 +91,7 @@ public SwaggerDocument GetSwagger(string rootUrl, string apiVersion)
.Where(apiDesc => !(_options.IgnoreObsoleteActions && apiDesc.IsObsolete()))
.OrderBy(_options.GroupingKeySelector, _options.GroupingKeyComparer)
.GroupBy(apiDesc => apiDesc.RelativePathSansQueryString())
.ToDictionary(group => "/" + group.Key, group => CreatePathItem(group, schemaRegistry));
.ToDictionary(group => "/" + group.Key, group => CreatePathItem(@group, schemaRegistry));

var rootUri = new Uri(rootUrl);
var port = !rootUri.IsDefaultPort ? ":" + rootUri.Port : string.Empty;
Expand Down Expand Up @@ -200,23 +201,25 @@ private Operation CreateOperation(ApiDescription apiDescription, SchemaRegistry
Contract.Requires(schemaRegistry != null);
Contract.Requires(apiDescription.ParameterDescriptions != null);


var edmModel = ((ODataRoute)apiDescription.Route).GetEdmModel();

var parameters = apiDescription.ParameterDescriptions
.Select(paramDesc =>
{
var inPath = apiDescription.RelativePathSansQueryString().Contains("{" + paramDesc.Name + "}");
var swaggerApiParameterDescription = paramDesc as SwaggerApiParameterDescription;
return swaggerApiParameterDescription != null
? CreateParameter(swaggerApiParameterDescription, inPath, schemaRegistry)
: CreateParameter(paramDesc, inPath, schemaRegistry);
? CreateParameter(swaggerApiParameterDescription, inPath, schemaRegistry, edmModel)
: CreateParameter(paramDesc, inPath, schemaRegistry, edmModel);
})
.ToList();

var responses = new Dictionary<string, Response>();
var responseType = apiDescription.ResponseType();
if (responseType == null || responseType == typeof(void))
responses.Add("204", new Response { description = "No Content" });
else
responses.Add("200", new Response { description = "OK", schema = schemaRegistry.GetOrRegisterResponseType(responseType) });
responses.Add("200", new Response { description = "OK", schema = schemaRegistry.GetOrRegisterResponseType(edmModel, responseType) });

var operation = new Operation
{
Expand All @@ -239,7 +242,7 @@ private Operation CreateOperation(ApiDescription apiDescription, SchemaRegistry
return operation;
}

private static Parameter CreateParameter(ApiParameterDescription paramDesc, bool inPath, SchemaRegistry schemaRegistry)
private static Parameter CreateParameter(ApiParameterDescription paramDesc, bool inPath, SchemaRegistry schemaRegistry, IEdmModel edmModel)
{
Contract.Requires(paramDesc != null);
Contract.Requires(schemaRegistry != null);
Expand All @@ -257,7 +260,7 @@ private static Parameter CreateParameter(ApiParameterDescription paramDesc, bool
@default = paramDesc.ParameterDescriptor.DefaultValue
};

var schema = schemaRegistry.GetOrRegisterParameterType(paramDesc.ParameterDescriptor);
var schema = schemaRegistry.GetOrRegisterParameterType(edmModel, paramDesc.ParameterDescriptor);
if (parameter.@in == "body")
parameter.schema = schema;
else
Expand All @@ -266,7 +269,7 @@ private static Parameter CreateParameter(ApiParameterDescription paramDesc, bool
return parameter;
}

private static Parameter CreateParameter(SwaggerApiParameterDescription paramDesc, bool inPath, SchemaRegistry schemaRegistry)
private static Parameter CreateParameter(SwaggerApiParameterDescription paramDesc, bool inPath, SchemaRegistry schemaRegistry, IEdmModel edmModel)
{
Contract.Requires(paramDesc != null);
Contract.Requires(schemaRegistry != null);
Expand All @@ -288,7 +291,7 @@ private static Parameter CreateParameter(SwaggerApiParameterDescription paramDes

var parameterType = paramDesc.ParameterDescriptor.ParameterType;
Contract.Assume(parameterType != null);
var schema = schemaRegistry.GetOrRegisterParameterType(paramDesc.ParameterDescriptor);
var schema = schemaRegistry.GetOrRegisterParameterType(edmModel, paramDesc.ParameterDescriptor);
if (parameter.@in == "body")
parameter.schema = schema;
else
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.12.0")]
[assembly: AssemblyInformationalVersion("2.12.1")]
Loading

0 comments on commit 3d277c7

Please sign in to comment.