Фильтровать по строке запроса динамически в MVC Core? - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть метод get, подобный этому ...

[HttpGet]
public async Task<ActionResult<IEnumerable<Customer>>> GetCustomers()
{
    var queryString = HttpContext.Request.Query;
    return await _context.Customers.Take(7).ToListAsync();
}

, и я хочу передать строку запроса, подобную этой:

https://localhost:44315/api/customer?param1=1&param2=String Value

Я хотел бы сделать это безнеобходимость объявить каждый параметр в моем списке параметров.например,

[HttpGet]
public async Task<ActionResult<IEnumerable<Customer>>> GetCustomers(int param1, string param2)
{
    var queryString = HttpContext.Request.Query;
    return await _context.Customers.Take(7).ToListAsync();
}

Я хочу избежать этого, потому что у моего класса есть несколько десятков параметров.Я знаю, что вы можете связывать с [FromQuery] Customer customer, но я не думаю, что это именно то, что я ищу.

Есть ли способ сделать это динамически?

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Я закончил тем, что делал что-то вроде

   //GET: api/customer
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Customer>>> GetCustomers()
    {
        var queryParams = HttpContext.Request.Query;
        var collection = _context.Customers.FilterByQueryParams(queryParams);
        return await Task.FromResult(collection.ToList());
    }

, а затем в отдельном классе

public static class DynamicFilterExtensionMethods
{
    public static IEnumerable<T> FilterByQueryParams<T>(this IEnumerable<T> collection, IQueryCollection queryParams) where T : new()
    {
        var classType = typeof(T);
        var propList = classType.GetProperties();
        //accountNumber ==> accountNumber, AccountNumber ==> accountNumber
        var props = new Dictionary<string, PropertyInfo>(propList.Select(x => new KeyValuePair<string, PropertyInfo>(Char.ToLowerInvariant(x.Name[0]) + x.Name.Substring(1), x)));

        foreach (var param in queryParams) {
            if (props.ContainsKey(param.Key)) {
                var prop = props[param.Key];
                   if (prop.PropertyType.IsPrimitive) {
                    if (param.Value.Count == 1)
                    {
                        collection = collection.Where(x => prop.GetValue(x, null).ToString() == param.Value.First());
                    }
                    else {
                        var aggregate = new List<T>();
                        foreach (var value in param.Value) {
                            aggregate = aggregate.Union<T>(collection.Where(x => prop.GetValue(x, null).ToString() == value)).ToList();
                        }
                        collection = aggregate.AsEnumerable();
                    }
                }
            }
        }

        return collection;
    }
}

Здесь еще многое нужно сделать, но я думаю, что этовсе в порядке.

0 голосов
/ 23 февраля 2019

Если вы просто хотите получить доступ к параметрам запроса через HttpContext и забыть о параметрах действия, вы можете просто полностью пропустить параметры.ASP.NET Core не оценивает строку запроса как часть маршрута действия (что также означает, что вы не можете создавать перегрузки на основе параметров запроса, если вы не укажете другой маршрут через атрибут маршрутизации).

...