[英]ASP.NET MVC Web API and passing oData query
I'm currently executing Web API with oData filter requests as follows: 我目前正在使用oData过滤器请求执行Web API,如下所示:
public IQueryable<OrganizationViewModel> Get(ODataQueryOptions<Organization> oDataQuery)
{
var query = new FindOrganizationsQuery(oDataQuery);
var result =_findOrganizationsQueryHandler.Execute(query);
return result.Organizations.Select(o => new OrganizationViewModel { Id = o.PublicId, Name = o.Name });
}
The handler looks like: 处理程序看起来像:
public FindOrganizationsQueryResult Execute(FindOrganizationsQuery request)
{
var organizations = request.ODataQuery.ApplyTo(_mgpQueryContext.Organizations).Cast<Organization>();
return new FindOrganizationsQueryResult(organizations);
}
And the query class looks like: 查询类看起来像:
public class FindOrganizationsQuery
{
public FindOrganizationsQuery(ODataQueryOptions<Organization> oDataQuery)
{
ODataQuery = oDataQuery;
}
public ODataQueryOptions<Organization> ODataQuery { get; set; }
}
So if I pass an oData filter with the request, it is handled nicely and this all works fine. 因此,如果我通过请求传递oData过滤器,它处理得很好,这一切都正常。
But now, instead of passing the type ODataQueryOptions to the Get operation, I would like to have the FindOrganizationsQuery class, like: 但是现在,我不想将类型ODataQueryOptions传递给Get操作,而是希望有FindOrganizationsQuery类,如:
public IQueryable<OrganizationViewModel> FindOrganizations(FindOrganizationsQuery query)
{
// query is null
}
However, the query parameters is always null. 但是,查询参数始终为null。 How can I pass the oData filter if the ODataQueryOptions parameters is in another class? 如果ODataQueryOptions参数在另一个类中,我如何传递oData过滤器?
You can write a custom parameter binding attribute for FindOrganizationsQuery
the same way we do for ODataQueryOptions
and then attribute your FindOrganizationsQuery
with that attribute. 您可以像我们为ODataQueryOptions
一样编写FindOrganizationsQuery
的自定义参数绑定属性,然后使用该属性对FindOrganizationsQuery
进行属性化。
Some sample code below, 下面是一些示例代码,
public class CustomQueryBindingAttribute : ParameterBindingAttribute
{
public override HttpParameterBinding GetBinding(HttpParameterDescriptor parameter)
{
return new CustomQueryBinding(parameter);
}
internal class CustomQueryBinding : HttpParameterBinding
{
public CustomQueryBinding(HttpParameterDescriptor parameter)
: base(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;
// Assuming all custom queries have this public property.
Type oDataQueryOptionsOfTType = parameterType.GetProperty("ODataQuery").PropertyType;
object odataQueryOptions = Activator.CreateInstance(oDataQueryOptionsOfTType, queryContext, request);
return Activator.CreateInstance(parameterType, odataQueryOptions);
}
}
}
and the extension method I copied from web API source code as it is not public. 我从web API源代码复制的扩展方法因为它不公开。
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.