ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – ASP.NET MVC Web API并传递oData查询

2019-07-09 03:08:47  阅读:216  来源: 互联网

标签:c asp-net-web-api odata asp-net-web-api-odata


我目前正在使用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 });
}

处理程序看起来像:

public FindOrganizationsQueryResult Execute(FindOrganizationsQuery request)
{
    var organizations = request.ODataQuery.ApplyTo(_mgpQueryContext.Organizations).Cast<Organization>();            
    return new FindOrganizationsQueryResult(organizations);
}

查询类看起来像:

public class FindOrganizationsQuery
{
    public FindOrganizationsQuery(ODataQueryOptions<Organization> oDataQuery)
    {
        ODataQuery = oDataQuery;
    }
    public ODataQueryOptions<Organization> ODataQuery { get; set; }
}

因此,如果我通过请求传递oData过滤器,它处理得很好,这一切都正常.

但是现在,我不想将类型ODataQueryOptions传递给Get操作,而是希望有FindOrganizationsQuery类,如:

public IQueryable<OrganizationViewModel> FindOrganizations(FindOrganizationsQuery query)
{
    // query is null
}

但是,查询参数始终为null.如果ODataQueryOptions参数在另一个类中,我如何传递oData过滤器?

解决方法:

您可以为我们为ODataQueryOptions执行的same way的FindOrganizationsQuery编写自定义参数绑定属性,然后使用该属性对FindOrganizationsQuery进行属性.

下面是一些示例代码,

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);
        }
    }
}

我从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;
    }
}

我有完整的样品here.

标签:c,asp-net-web-api,odata,asp-net-web-api-odata
来源: https://codeday.me/bug/20190709/1408559.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有