Skip to content

Instantly share code, notes, and snippets.

@raghuramn
Last active December 21, 2015 03:29
Show Gist options
  • Save raghuramn/6242965 to your computer and use it in GitHub Desktop.
Save raghuramn/6242965 to your computer and use it in GitHub Desktop.
Sample showing parameter binding for custom ODataQueryOptions.
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Metadata;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Query;
using Microsoft.Data.Edm;
namespace ConsoleApplication27
{
class Program
{
static void Main(string[] args)
{
HttpServer server = new HttpServer();
server.Configuration.Routes.MapHttpRoute("default", "{controller}");
HttpClient client = new HttpClient(server);
var response = client.GetAsync("http://localhost/Org?$filter=ID eq 42").Result;
Console.WriteLine(response);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
}
public class OrgController : ApiController
{
public string Get(FindOrganizationsQuery query)
{
return query.ODataQuery.Filter.RawValue;
}
}
public class CustomQueryBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
return new CustomQueryBinding(parameter);
}
internal class CustomQueryBinding : HttpParameterBinding
{
public CustomQueryBinding(HttpParameterDescriptor parameter)
: base(parameter)
{
}
public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider,
HttpActionContext actionContext, CancellationToken cancellationToken)
{
IEdmModel model = actionContext.Request.GetEdmModel() ?? actionContext.ActionDescriptor.GetEdmModel(typeof(Organization));
ODataQueryContext queryContext = new ODataQueryContext(model, typeof(Organization));
object customQuery = CreateCustomQuery(queryContext, actionContext.Request);
SetValue(actionContext, customQuery);
return Task.FromResult(0);
}
private object CreateCustomQuery(ODataQueryContext queryContext, HttpRequestMessage request)
{
Type parameterType = Descriptor.ParameterType;
// Get the query options type, assuming all custom queries have this property.
Type oDataQueryOptionsOfTType = parameterType.GetProperty("ODataQuery").PropertyType;
object odataQueryOptions = Activator.CreateInstance(oDataQueryOptionsOfTType, queryContext, request);
return Activator.CreateInstance(parameterType, odataQueryOptions);
}
}
}
[CustomQueryBinding]
public class FindOrganizationsQuery
{
public FindOrganizationsQuery(ODataQueryOptions<Organization> oDataQuery)
{
ODataQuery = oDataQuery;
}
public ODataQueryOptions<Organization> ODataQuery { get; set; }
}
public class Organization
{
public int ID { get; set; }
}
public static class HttpActionDescriptorExtensions
{
internal const string EdmModelKey = "MS_EdmModel";
internal static IEdmModel GetEdmModel(this HttpActionDescriptor actionDescriptor, Type entityClrType)
{
// save the EdmModel to the action descriptor
return actionDescriptor.Properties.GetOrAdd(EdmModelKey + entityClrType.FullName, _ =>
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(actionDescriptor.Configuration, isQueryCompositionMode: true);
EntityTypeConfiguration entityTypeConfiguration = builder.AddEntity(entityClrType);
builder.AddEntitySet(entityClrType.Name, entityTypeConfiguration);
IEdmModel edmModel = builder.GetEdmModel();
return edmModel;
}) as IEdmModel;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment