deprecating ODATA support in 3.x until we make the protocol work properly, also the library from microsoft is quite inconsistent when it comes to case ofthe property in their convention vs the property names in urls.

This commit is contained in:
David Lebee 2021-08-13 12:21:27 -04:00
parent 1c44d39d90
commit 36bf2a9096
18 changed files with 17 additions and 281 deletions

View File

@ -5,17 +5,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentValidation.AspNetCore" Version="9.5.0" /> <PackageReference Include="FluentValidation.AspNetCore" Version="10.3.0" />
<PackageReference Include="HotChocolate.AspNetCore" Version="11.0.9" /> <PackageReference Include="HotChocolate.AspNetCore" Version="11.3.4" />
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.5.5" /> <PackageReference Include="Microsoft.AspNetCore.OData" Version="8.0.1" />
<PackageReference Include="PoweredSoft.Data" Version="2.0.0" /> <PackageReference Include="PoweredSoft.Data" Version="3.0.0-alpha" />
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.6.3" /> <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.1.5" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" /> <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.1.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore.OData\PoweredSoft.CQRS.AspNetCore.OData.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore\PoweredSoft.CQRS.AspNetCore.csproj" /> <ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore\PoweredSoft.CQRS.AspNetCore.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" /> <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.Abstractions\PoweredSoft.CQRS.DynamicQuery.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.AspNetCore\PoweredSoft.CQRS.DynamicQuery.AspNetCore.csproj" /> <ProjectReference Include="..\PoweredSoft.CQRS.DynamicQuery.AspNetCore\PoweredSoft.CQRS.DynamicQuery.AspNetCore.csproj" />

View File

@ -24,8 +24,8 @@ using System.Linq;
using PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery; using PoweredSoft.CQRS.GraphQL.HotChocolate.DynamicQuery;
using PoweredSoft.CQRS.Abstractions.Security; using PoweredSoft.CQRS.Abstractions.Security;
using Demo.Security; using Demo.Security;
using Microsoft.AspNet.OData.Extensions;
using PoweredSoft.CQRS.FluentValidation; using PoweredSoft.CQRS.FluentValidation;
using Microsoft.AspNetCore.OData;
namespace Demo namespace Demo
{ {
@ -53,14 +53,12 @@ namespace Demo
services.AddPoweredSoftDynamicQuery(); services.AddPoweredSoftDynamicQuery();
services.AddPoweredSoftCQRS(); services.AddPoweredSoftCQRS();
services.AddOData();
services services
.AddControllers() .AddControllers()
.AddPoweredSoftQueries() .AddPoweredSoftQueries()
.AddPoweredSoftCommands() .AddPoweredSoftCommands()
.AddPoweredSoftDynamicQueries() .AddPoweredSoftDynamicQueries()
.AddPoweredSoftODataQueries()
.AddFluentValidation(); .AddFluentValidation();
services services
@ -138,10 +136,6 @@ namespace Demo
{ {
endpoints.MapControllers(); endpoints.MapControllers();
endpoints.MapGraphQL(); endpoints.MapGraphQL();
endpoints.Select().Filter().OrderBy().Count().MaxTop(10);
endpoints.MapODataRoute("odata", "odata", endpoints.GetPoweredSoftODataEdmModel());
}); });
} }
} }

View File

@ -8,6 +8,6 @@
<Authors>PoweredSoft Team</Authors> <Authors>PoweredSoft Team</Authors>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Copyright>Powered Softwares Inc.</Copyright>
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;amp;r=g&amp;amp;d=retro</PackageIconUrl>
<Company>PoweredSoft</Company>
<Authors>PoweredSoft Team</Authors>
</PropertyGroup>
</Project>

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace PoweredSoft.CQRS.AspNetCore.OData.Abstractions
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class QueryOdataControllerIgnoreAttribute : Attribute
{
}
}

View File

@ -1,44 +0,0 @@
using Microsoft.AspNet.OData.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OData.Edm;
using PoweredSoft.CQRS.Abstractions.Discovery;
using PoweredSoft.CQRS.AspNetCore.OData.Abstractions;
using System.Linq;
using System.Reflection;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public static class EndpointExstensions
{
public static IEdmModel GetPoweredSoftODataEdmModel(this IEndpointRouteBuilder endpoint)
{
var queryDiscovery = endpoint.ServiceProvider.GetRequiredService<IQueryDiscovery>();
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EnableLowerCamelCase();
foreach(var q in queryDiscovery.GetQueries())
{
var ignoreAttribute = q.QueryType.GetCustomAttribute<QueryOdataControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (q.Category != "BasicQuery")
continue;
var isQueryable = q.QueryResultType.Namespace == "System.Linq" && q.QueryResultType.Name.Contains("IQueryable");
if (!isQueryable)
continue;
var entityType = q.QueryResultType.GetGenericArguments().First();
odataBuilder.GetType().GetMethod("EntitySet").MakeGenericMethod(entityType).Invoke(odataBuilder, new object[] {
q.LowerCamelCaseName
});
}
return odataBuilder.GetEdmModel();
}
}
}

View File

@ -1,46 +0,0 @@
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Net.Http.Headers;
using PoweredSoft.CQRS.AspNetCore.OData;
using System;
using System.Linq;
using System.Text;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public static class MvcBuilderExtensions
{
public static IMvcBuilder AddPoweredSoftODataQueries(this IMvcBuilder builder, Action<QueryODataControllerOptions> configuration = null)
{
var options = new QueryODataControllerOptions();
configuration?.Invoke(options);
var services = builder.Services;
var serviceProvider = services.BuildServiceProvider();
builder.AddMvcOptions(o => o.Conventions.Add(new QueryODataControllerConvention(serviceProvider)));
builder.ConfigureApplicationPartManager(m => m.FeatureProviders.Add(new QueryODataControllerFeatureProvider(serviceProvider)));
if (options.FixODataSwagger)
builder.FixODataSwagger();
return builder;
}
public static IMvcBuilder FixODataSwagger(this IMvcBuilder builder)
{
builder.AddMvcOptions(options =>
{
foreach (var outputFormatter in options.OutputFormatters.OfType<OutputFormatter>().Where(x => x.SupportedMediaTypes.Count == 0))
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
foreach (var inputFormatter in options.InputFormatters.OfType<InputFormatter>().Where(x => x.SupportedMediaTypes.Count == 0))
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
}
});
return builder;
}
}
}

View File

@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<Copyright>Powered Softwares Inc.</Copyright>
<PackageIconUrl>https://secure.gravatar.com/avatar/4e32f73820c16718909a06c2927f1f8b?s=512&amp;amp;r=g&amp;amp;d=retro</PackageIconUrl>
<Company>PoweredSoft</Company>
<Authors>PoweredSoft Team</Authors>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OData" Version="7.5.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PoweredSoft.CQRS.Abstractions\PoweredSoft.CQRS.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore.OData.Abstractions\PoweredSoft.CQRS.AspNetCore.OData.Abstractions.csproj" />
<ProjectReference Include="..\PoweredSoft.CQRS.AspNetCore\PoweredSoft.CQRS.AspNetCore.csproj" />
</ItemGroup>
</Project>

View File

@ -1,23 +0,0 @@
using Microsoft.AspNet.OData;
using Microsoft.AspNetCore.Mvc;
using PoweredSoft.CQRS.Abstractions;
using PoweredSoft.CQRS.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace PoweredSoft.CQRS.AspNetCore.OData
{
[Route("api/odata/[controller]")]
[ApiExplorerSettings(IgnoreApi = true)]
public class QueryODataController<TQuery, TQueryResult> : ODataController
where TQuery : class
{
[EnableQuery, HttpGet, QueryControllerAuthorization]
public async Task<TQueryResult> Get([FromServices]IQueryHandler<TQuery, TQueryResult> queryHandler, [FromQuery]TQuery query)
{
var result = await queryHandler.HandleAsync(query, HttpContext.RequestAborted);
return result;
}
}
}

View File

@ -1,29 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.Extensions.DependencyInjection;
using PoweredSoft.CQRS.Abstractions.Discovery;
using System;
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public class QueryODataControllerConvention : IControllerModelConvention
{
private readonly IServiceProvider serviceProvider;
public QueryODataControllerConvention(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public void Apply(ControllerModel controller)
{
if (controller.ControllerType.IsGenericType && controller.ControllerType.Name.Contains("QueryODataController") && controller.ControllerType.Assembly == typeof(QueryODataControllerConvention).Assembly)
{
var genericType = controller.ControllerType.GenericTypeArguments[0];
var queryDiscovery = this.serviceProvider.GetRequiredService<IQueryDiscovery>();
var query = queryDiscovery.FindQuery(genericType);
controller.ControllerName = $"{query.LowerCamelCaseName}";
}
}
}
}

View File

@ -1,45 +0,0 @@
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using PoweredSoft.CQRS.Abstractions.Discovery;
using PoweredSoft.CQRS.AspNetCore.Abstractions.Attributes;
using PoweredSoft.CQRS.AspNetCore.OData.Abstractions;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace PoweredSoft.CQRS.AspNetCore.OData
{
public class QueryODataControllerFeatureProvider : IApplicationFeatureProvider<ControllerFeature>
{
private readonly ServiceProvider serviceProvider;
public QueryODataControllerFeatureProvider(ServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public void PopulateFeature(IEnumerable<ApplicationPart> parts, ControllerFeature feature)
{
var queryDiscovery = this.serviceProvider.GetRequiredService<IQueryDiscovery>();
foreach (var f in queryDiscovery.GetQueries())
{
var ignoreAttribute = f.QueryType.GetCustomAttribute<QueryOdataControllerIgnoreAttribute>();
if (ignoreAttribute != null)
continue;
if (f.Category != "BasicQuery")
continue;
var isQueryable = f.QueryResultType.Namespace == "System.Linq" && f.QueryResultType.Name.Contains("IQueryable");
if (!isQueryable)
continue;
var controllerType = typeof(QueryODataController<,>).MakeGenericType(f.QueryType, f.QueryResultType);
var controllerTypeInfo = controllerType.GetTypeInfo();
feature.Controllers.Add(controllerTypeInfo);
}
}
}
}

View File

@ -1,11 +0,0 @@
namespace PoweredSoft.CQRS.AspNetCore.Mvc
{
public class QueryODataControllerOptions
{
public bool FixODataSwagger { get; set; } = true;
public QueryODataControllerOptions()
{
}
}
}

View File

@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentValidation" Version="9.5.0" /> <PackageReference Include="FluentValidation" Version="10.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="PoweredSoft.DynamicQuery" Version="2.1.5" /> <PackageReference Include="PoweredSoft.DynamicQuery" Version="2.1.5" />
</ItemGroup> </ItemGroup>

View File

@ -9,8 +9,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FluentValidation" Version="9.5.0" /> <PackageReference Include="FluentValidation" Version="10.3.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -9,7 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HotChocolate" Version="11.0.9" /> <PackageReference Include="HotChocolate" Version="11.3.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -9,8 +9,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="HotChocolate" Version="11.0.9" /> <PackageReference Include="HotChocolate" Version="11.3.4" />
<PackageReference Include="HotChocolate.Data" Version="11.0.9" /> <PackageReference Include="HotChocolate.Data" Version="11.3.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -35,11 +35,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.GraphQL.Ho
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.GraphQL.DynamicQuery", "PoweredSoft.CQRS.GraphQL.DynamicQuery\PoweredSoft.CQRS.GraphQL.DynamicQuery.csproj", "{34B27880-A5D5-47EA-A5FA-86E04E0F7A21}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.GraphQL.DynamicQuery", "PoweredSoft.CQRS.GraphQL.DynamicQuery\PoweredSoft.CQRS.GraphQL.DynamicQuery.csproj", "{34B27880-A5D5-47EA-A5FA-86E04E0F7A21}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.AspNetCore.OData", "PoweredSoft.CQRS.AspNetCore.OData\PoweredSoft.CQRS.AspNetCore.OData.csproj", "{04459C2D-B02F-4FF0-8D66-73042F27C7CC}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.FluentValidation", "PoweredSoft.CQRS.FluentValidation\PoweredSoft.CQRS.FluentValidation.csproj", "{70BD37C4-7497-474D-9A40-A701203971D8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PoweredSoft.CQRS.AspNetCore.OData.Abstractions", "PoweredSoft.CQRS.AspNetCore.OData.Abstractions\PoweredSoft.CQRS.AspNetCore.OData.Abstractions.csproj", "{9B65B727-C088-4562-A607-8BD5B5EFF289}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoweredSoft.CQRS.FluentValidation", "PoweredSoft.CQRS.FluentValidation\PoweredSoft.CQRS.FluentValidation.csproj", "{70BD37C4-7497-474D-9A40-A701203971D8}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -99,14 +95,6 @@ Global
{34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Debug|Any CPU.Build.0 = Debug|Any CPU {34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Release|Any CPU.ActiveCfg = Release|Any CPU {34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Release|Any CPU.Build.0 = Release|Any CPU {34B27880-A5D5-47EA-A5FA-86E04E0F7A21}.Release|Any CPU.Build.0 = Release|Any CPU
{04459C2D-B02F-4FF0-8D66-73042F27C7CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04459C2D-B02F-4FF0-8D66-73042F27C7CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04459C2D-B02F-4FF0-8D66-73042F27C7CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04459C2D-B02F-4FF0-8D66-73042F27C7CC}.Release|Any CPU.Build.0 = Release|Any CPU
{9B65B727-C088-4562-A607-8BD5B5EFF289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B65B727-C088-4562-A607-8BD5B5EFF289}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B65B727-C088-4562-A607-8BD5B5EFF289}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B65B727-C088-4562-A607-8BD5B5EFF289}.Release|Any CPU.Build.0 = Release|Any CPU
{70BD37C4-7497-474D-9A40-A701203971D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {70BD37C4-7497-474D-9A40-A701203971D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{70BD37C4-7497-474D-9A40-A701203971D8}.Debug|Any CPU.Build.0 = Debug|Any CPU {70BD37C4-7497-474D-9A40-A701203971D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70BD37C4-7497-474D-9A40-A701203971D8}.Release|Any CPU.ActiveCfg = Release|Any CPU {70BD37C4-7497-474D-9A40-A701203971D8}.Release|Any CPU.ActiveCfg = Release|Any CPU