简体   繁体   中英

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 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' or MessageType eq '1' (This works fine)

GET https://localhost:44378/v1/RoutePrefix/Route ?$filter=Id eq '1234' and MessageType eq '1' (This one is not working. Response value is always [])

Looks like the filter with "and" operator is not working. "Or" operator works fine for me.

I have the below code in my 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. In the Main get method, I return as Ok(List.AsQueryable()).

I decorated the controller with [EnableQuery] attribute and Implemented ODataController as below:

[EnableQuery] public class RouteController : ODataController

and the Get method looks like this:

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. 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. 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. It gets replaced with different value – Kumaraguru 1 min ago edit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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