WebAPI 2 Odata Filter not working

2019-09-02 21:03发布

问题:

I have a problem with using multiple filters on my WebAPI 2 Odata project.

We only want JSON output and only have one object type to query so we set the url to "/" without the possibility to use a different controller.

I have an object I want to query with the following properties:

 public class Content
 {
    public int Id { get; set; }
    public string Title { get; set; }
    public string Excerpt { get; set; }
    public string Link { get; set; }
    public IList<Tag> Tags  { get; set; }
 }

 public class Tag 
 {
    public string Id { get; set; }
    public string Name { get; set; }
 }

And the controller code looks like this:

public class ContentController : ApiController
{

    private readonly IContentRepository _repository;

    // constructor
    public ContentController(IContentRepository repository)
    {
        _repository = repository;
    }

    [Queryable]
    public IQueryable<Content> Index()
    {
        // IContentRepository.GetAll returns an IEnumerable List of Content
        return _repository.GetAll().AsQueryable();
    }
}

Now, I've mocked some testdata with adding multiple objects to the repository that have multiple tags with values set to either (test1, test2 or test3). Now when i Query

http://localhost:xxx?$filter=Tags/any(o: o/Id eq 'test1')

I get all objects with Tag/Id set to 'test1'. But if I query

http://localhost:xxx?$filter=Tags/any(o: o/Id eq 'test1' and o/Id eq 'test2')

I get no result (JSON return = []). But it should return objects that have both tags.

What am I doing wrong?

EDIT: My sample data JSON looks like this:

[
 {
   "Id": 1,
   "Title": "TESTOBJECT 1",
   "Excerpt": "",
   "Link": "",
   "Tags": [
             {
               "Id": "test1",
               "Name": "Test Tag 1",
             }
           ],
 },
 {
   "Id": 2,
   "Title": "TESTOBJECT 2",
   "Excerpt": "",
   "Link": "",
   "Tags": [
             {
               "Id": "test2",
               "Name": "Test Tag 2",
             }
           ],
 },
 {
   "Id": 3,
   "Title": "TESTOBJECT 3",
   "Excerpt": "",
   "Link": "",
   "Tags": [
             {
               "Id": "test3",
               "Name": "Test Tag 3",
             }
           ],
 },
 {
   "Id": 4,
   "Title": "TESTOBJECT 4",
   "Excerpt": "",
   "Link": "",
   "Tags": [
             {
               "Id": "test1",
               "Name": "Test Tag 1",
             },
             {
               "Id": "test2",
               "Name": "Test Tag 2",
             }
           ],
 },
 {
   "Id": 5,
   "Title": "TESTOBJECT 5",
   "Excerpt": "",
   "Link": "",
   "Tags": [
             {
               "Id": "test1",
               "Name": "Test Tag 1",
             }
           ],
 }
]

Now query one gives me object 1,4,5 and I would expect query two to give me object 4. How can I accomplish this with odata?

回答1:

Did you want this?

http://localhost:xxx?$filter=Tags/any(o: o/Id eq 'test1') and Tags/any(o: o/Id eq 'test2')


回答2:

((X == "test1") AND (X == "test2")) will always return false!

If you want to identify Tags whose property Id is test1 or test2, use the or operator.