Last active
April 20, 2022 15:10
-
-
Save Pzixel/cf09ca4f360356d8749a9fe2049d3169 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using Microsoft.AspNet.OData; | |
using Microsoft.AspNet.OData.Builder; | |
using Microsoft.AspNet.OData.Extensions; | |
using Microsoft.AspNet.OData.Formatter; | |
using Microsoft.AspNetCore.Builder; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Net.Http.Headers; | |
using Microsoft.OData.Edm; | |
using Microsoft.OData.UriParser; | |
namespace My | |
{ | |
public static class XOdataStartup | |
{ | |
public static IServiceCollection RegisterOData(this IServiceCollection services) | |
{ | |
services.AddOData(); | |
// fix invalid OData media type: https://github.com/OData/WebApi/issues/2024 | |
// multiple "AddMvcCore" calls are ok | |
services.AddMvcCore(options => | |
{ | |
foreach (var outputFormatter in options.OutputFormatters.OfType<ODataOutputFormatter>() | |
.Where(x => x.SupportedMediaTypes.Count == 0)) | |
{ | |
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata")); | |
} | |
foreach (var inputFormatter in options.InputFormatters.OfType<ODataInputFormatter>() | |
.Where(x => x.SupportedMediaTypes.Count == 0)) | |
{ | |
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata")); | |
} | |
}); | |
return services; | |
} | |
public static IApplicationBuilder UseMvcWithOData(this IApplicationBuilder app, | |
string routePrefix, | |
Action<ODataConventionModelBuilder> builderConfigurator, | |
params Delegate[] customFunctions) | |
{ | |
var odataModelBuilder = GetOdataBuilder(app, builderConfigurator, customFunctions); | |
app.UseEndpoints(endpoints => | |
{ | |
endpoints.MapControllers(); | |
endpoints | |
.SetTimeZoneInfo(TimeZoneInfo.Utc) | |
.Select() | |
.Expand() | |
.Filter() | |
.OrderBy() | |
.MaxTop(null) | |
.Count(); | |
endpoints.MapODataRoute("ODataRoute", routePrefix, odataModelBuilder.GetEdmModel()); | |
}); | |
return app; | |
} | |
private static ODataConventionModelBuilder GetOdataBuilder(IApplicationBuilder app, | |
Action<ODataConventionModelBuilder> builderConfigurator, | |
params Delegate[] customFunctions) | |
{ | |
var builder = new ODataConventionModelBuilder(app.ApplicationServices); | |
builderConfigurator(builder); | |
foreach (var customFunction in customFunctions) | |
{ | |
RegisterCustomFunction(customFunction); | |
} | |
return builder; | |
} | |
public static ODataConventionModelBuilder AddEntity<T, TKey>(this ODataConventionModelBuilder builder, Expression<Func<T, TKey>> keyDefinitionExpression) | |
where T : class | |
{ | |
var entity = builder.EntitySet<T>(typeof(T).Name.ToLower()); | |
entity.EntityType.HasKey(keyDefinitionExpression); | |
return builder; | |
} | |
private static void RegisterCustomFunction(Delegate method) | |
{ | |
var methodInfo = method.Method; | |
var returnType = TypeToReference(methodInfo.ReturnType); | |
var args = methodInfo.GetParameters() | |
.Select(x => TypeToReference(x.ParameterType)) | |
.ToArray(); | |
var signature = new FunctionSignatureWithReturnType(returnType, args); | |
ODataUriFunctions.AddCustomUriFunction(methodInfo.Name, signature, methodInfo); | |
} | |
private static IEdmTypeReference TypeToReference(Type type) | |
{ | |
var primitiveTypeKind = EdmCoreModel.Instance.GetPrimitiveTypeKind(type.Name); | |
var isNullable = type.IsClass || Nullable.GetUnderlyingType(type) != null; | |
return new EdmPrimitiveTypeReference( | |
EdmCoreModel.Instance.GetPrimitiveType(primitiveTypeKind), | |
isNullable); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static IApplicationBuilder UseMvcWithOData(this IApplicationBuilder app) => | |
app.UseMvcWithOData($"{ApiConstant.Prefix}odata", | |
builder => | |
{ | |
builder | |
.AddMyEntity<Order>() | |
}, | |
new Func<string, string, bool>(CustomFunctions.ContainsIgnoreCase), | |
new Func<string, string, bool>(CustomFunctions.StartsWithIgnoreCase)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment