skip to Main Content

I need to basically pass a list of objects each has 3 parameters variable name, operator, and value.

I have tried using

public async Task<ActionResult> GetAPIData([FromQuery] Condition[] conditions) 

where condition is

public class Condition
{
    public string variable { get; set; }
    public string op { get; set; }
    public double value { get; set; }
}

but I just can’t get it to pass the items across every time I call the API "conditions" is empty.

It’s a messy URL but swagger gives me

http://localhost:5001/api/datatable?conditions=%7B%0A%20%20%22variable%22%3A%20%22vara%22%2C%0A%20%20%22op%22%3A%20%22%3E%22%2C%0A%20%20%22value%22%3A%2020%0A%7D&conditions=%7B%0A%20%20%22variable%22%3A%20%22varb%22%2C%0A%20%20%22op%22%3A%20%22%3E%22%2C%0A%20%20%22value%22%3A%2010%0A%7D

var t = conditions.Length;
IQueryable<ScreenerData> query = _context.datatable;

foreach (var condition in conditions)
{
    string variable = condition.variable;
    string _operator = condition.op;
    double value = condition.value;

    switch (_operator)
    {
        case "==":
            query = query.Where(data => data.GetType().GetProperty(variable).GetValue(data, null).Equals(value));
            break;

        case "!=":
            query = query.Where(data => !data.GetType().GetProperty(variable).GetValue(data, null).Equals(value));
            break;

        case ">":
            query = query.Where(data => Convert.ToDouble(data.GetType().GetProperty(variable).GetValue(data, null)) > value);
            break;

        case "<":
            query = query.Where(data => Convert.ToDouble(data.GetType().GetProperty(variable).GetValue(data, null)) < value);
            break;

        // Handle other operators as needed

        default:
            // Handle unsupported operators or throw an exception
            return BadRequest("Unsupported operator");
    }
}

var filteredData = await query.Where(data => data.Data != null)
                  .Select(data => data.Id)
                  .ToListAsync();

filteredData basically returns the entire dataset because conditions is empty and thus no filtering based on the operator is happening.

2

Answers


  1. First I suggest you to not send this data as fromquery, but if you want to do with it here is the code to pass the array in fromquery from C#.

    {
        new Condition {
          Variable = "Variable1",
          Op = ">",
          Value = 10.5
        },
        new Condition {
          Variable = "Variable2",
          Op = "<",
          Value = 20.0
        }
        // Add more conditions as needed
    };
    
    var apiUrl = "http://localhost:5001/api/datatable";
    
    var queryString = string.Join("&", conditions.Select(c =>
        $"conditions=
         {Uri.EscapeDataString(c.Variable)}: 
         {Uri.EscapeDataString(c.Op)}
         {c.Value}")
    );
    
    var fullUrl = $"{apiUrl}?{queryString}";```
    
    And from PostMan you can call this API as:
    http://localhost:5001/api/datatable?conditions=Variable1:>:10.5&conditions=Variable2:<:20.0
    
    
    Login or Signup to reply.
  2. It seems that Swagger is currently unable to produce a correct query string for these cases. The correct query string is of the form ?conditions[0].variable=variable1&conditions[0].op=someOperator&conditions[0].value=10.5&conditions[1]... and you keep adding the same pattern, increasing the index counter for every condition.

    So as you have seen, the query string name conditions is not very pretty. I suggest you change your action signature to:

    public async Task<ActionResult> GetAPIData([FromQuery(Name = "cnd")] Condition[] conditions)
    

    This way, instead of using conditions[], you would use cnd[], which is shorter and singular.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search