简体   繁体   English

带有“and”运算符的 OData 过滤器在 Web Api 中不起作用

[英]OData filter with "and" operator not working in Web Api

I am creating a Web Api with single GET action which handles the below get requests.我正在创建一个带有单个 GET 操作的 Web Api,它处理以下 get 请求。

GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234'$select=Name (This one works fine) GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234'$select=Name (这个工作正常)

GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234' or MessageType eq '1' (This works fine) GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234' 或 MessageType eq '1' (这很好用)

GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234' and MessageType eq '1' (This one is not working. Response value is always []) GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234' and MessageType eq '1' (这个不起作用。响应值总是 [])

Looks like the filter with "and" operator is not working.看起来带有“and”运算符的过滤器不起作用。 "Or" operator works fine for me. “或”运算符对我来说很好用。

I have the below code in my webapiconfig.cs.我的 webapiconfig.cs 中有以下代码。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.MapODataServiceRoute("odata", "v1/RoutePrefix", GetEdmModel(), new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
        config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);
    }
    private static IEdmModel GetEdmModel()
    {
        ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
        builder.Namespace = "Default";
        builder.ContainerName = "DefaultContainer";
        builder.EntitySet<Model>("Route");
        builder.EntitySet<Model>("Route").EntityType.Filter(nameof(Model.Id));
        builder.EntitySet<Model>("Route").EntityType.Filter(nameof(Model.MessageType));
        var edmModel = builder.GetEdmModel();

        return edmModel;
    }
}

And in my controller, based on the number of filter paramerter, I call different method.在我的控制器中,根据过滤器参数的数量,我调用了不同的方法。 And both methods returns List as the response to the GET method.并且这两种方法都返回 List 作为对 GET 方法的响应。 In the Main get method, I return as Ok(List.AsQueryable()).在 Main get 方法中,我以 Ok(List.AsQueryable()) 的形式返回。

I decorated the controller with [EnableQuery] attribute and Implemented ODataController as below:我用 [EnableQuery] 属性装饰控制器并实现 ODataController 如下:

[EnableQuery] public class RouteController : ODataController [EnableQuery] 公共类 RouteController : ODataController

and the Get method looks like this: Get 方法如下所示:

public IHttpActionResult Get()
{
        List<Model> response = null;
        string cacheKey = string.Empty;
        var queryString = Request.RequestUri.PathAndQuery.Replace("/v1/RoutePrefix", "");
        var queryTokens = ParseQueryString(EdmModel, queryString);

        if (queryTokens == null || queryTokens.Any(a => string.IsNullOrWhiteSpace(a.Value)) || !queryTokens.ContainsKey(Constants.Id))
        {
            IList<ApiError> errors = new List<ApiError>() { new ApiError(Constants.InvalidQueryStringErrorCode, Constants.InvalidQueryStringErrorMessage) };
            return GenerateResponse(Request, HttpStatusCode.BadRequest, errors, null);
        }
        else
        {
            try
            {
                if (queryTokens.ContainsKey(Constants.MessageType))
                {
                    response = GetConfigurationByMessageTypeAndId(queryTokens);
                }
                else
                {
                    response = GetConfigurationById(queryTokens);
                }
            }
            catch (Exception ex)
            {
                var apiError = Utilities.CreateApiError(Constants.InternalServerError, Constants.InternalServerErrorMessage, null, null, null);
                IList<ApiError> apiErrors = new List<ApiError> { apiError };

                return GenerateResponse(Request, HttpStatusCode.InternalServerError, apiErrors, null);
            }

            if (response.Count > 0)
            {
                return Ok(response.AsQueryable());
            }
            else
            {
                return NotFound();
            }
        }
    }

Please let me know what am doing wrong.请让我知道我做错了什么。

Thanks谢谢

Issue resolved.The $filter system query option allows clients to filter a collection of resources that are addressed by a request URL.问题已解决。$filter 系统查询选项允许客户端过滤由请求 URL 寻址的资源集合。 The expression specified with $filter is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response.使用 $filter 指定的表达式会针对集合中的每个资源进行计算,并且只有表达式计算结果为 true 的项目才会包含在响应中。 Resources for which the expression evaluates to false or to null, or which reference properties that are unavailable due to permissions, are omitted from the response.My final collection was not having the original value that passed in the query string.表达式计算结果为 false 或 null 的资源,或者由于权限而无法使用的引用属性,将从响应中省略。我的最终集合没有在查询字符串中传递的原始值。 It gets replaced with different value – Kumaraguru 1 min ago edit它被替换为不同的值 – Kumaraguru 1 分钟前编辑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM