Как читать значения из строки запроса с помощью ASP.NET Core?

Я создаю один RESTful API с помощью ASP.NET Core MVC, и я хочу использовать параметры запроса для указания фильтрации и подкачки на ресурсе, который возвращает коллекцию.

В этом случае мне нужно прочитать значения, переданные в querystring, для фильтрации и выбора результатов для возврата.

Я уже выяснил, что внутри контроллера Get действие, получающее доступ к HttpContext.Request.Query, возвращает один IQueryCollection.

Проблема в том, что я не знаю, как она используется для извлечения значений. По правде говоря, я думал, что способ сделать это - использовать, например

string page = HttpContext.Request.Query["page"]

Проблема в том, что HttpContext.Request.Query["page"] не возвращает строку, а StringValues.

В любом случае, как использовать IQueryCollection для фактического чтения значений запроса?

Ответы

Ответ 2

Вы можете использовать метод ToString на IQueryCollection, который вернет желаемое значение, если указан один параметр page:

string page = HttpContext.Request.Query["page"].ToString();

если есть несколько значений, таких как ?page=1&page=2, тогда результат вызова ToString будет 1,2

Но, как предложил @mike-g в своем ответе, лучше использовать привязку к модели, а не напрямую обращаться к объекту HttpContext.Request.Query.

Ответ 3

Ядро ASP.NET автоматически свяжет form values route values и query strings по имени. Это означает, что вы можете просто сделать это:

[HttpGet()]
public IActionResult Get(int page)
{ ... }

MVC попытается связать данные запроса с параметрами действия по имени... ниже приведен список источников данных в том порядке, в котором просматривается привязка модели

  1. Form values: это значения формы, которые входят в HTTP-запрос с использованием метода POST. (включая запросы POST JQuery).

  2. Route values: набор значений маршрута, предоставляемых маршрутизацией

  3. Query strings запроса: часть строки запроса в URI.

Источник: как работает привязка модели


FYI, вы также можете комбинировать автоматические и явные подходы:

[HttpGet()]
public IActionResult Get(int page
     , [FromQuery(Name = "page-size")] int pageSize)
{ ... }

Ответ 4

Вот пример кода, который я использовал (с представлением.NET Core):

@{
    Microsoft.Extensions.Primitives.StringValues queryVal;

    if (Context.Request.Query.TryGetValue("yourKey", out queryVal) &&
        queryVal.FirstOrDefault() == "yourValue")
    {
    }
}

Ответ 5

Вы можете просто создать объект следующим образом:

public class SomeQuery
{
    public string SomeParameter { get; set; }
    public int? SomeParameter2 { get; set; }
}

А затем в контроллере просто сделать что-то вроде этого:

[HttpGet]
public IActionResult FindSomething([FromQuery] SomeQuery query)
{
    // Your implementation goes here..
}

Более того, вы можете создать модель API из:

[HttpGet]
public IActionResult GetSomething([FromRoute] int someId, [FromQuery] SomeQuery query)

чтобы:

[HttpGet]
public IActionResult GetSomething(ApiModel model)

public class ApiModel
{
    [FromRoute]
    public int SomeId { get; set; }
    [FromQuery]
    public string SomeParameter { get; set; }
    [FromQuery]
    public int? SomeParameter2 { get; set; }
}

Ответ 6

StringValues - это массив строк. Вы можете получить строковое значение, HttpContext.Request.Query["page"][0] индекс, например, HttpContext.Request.Query["page"][0].

Ответ 7

IQueryCollection имеет на нем TryGetValue(), который возвращает значение с данным ключом. Итак, если у вас есть параметр запроса с именем someInt, вы можете использовать его так:

var queryString = httpContext.Request.Query;
StringValues someInt;
queryString.TryGetValue("someInt", out someInt);
var daRealInt = int.Parse(someInt);

Обратите внимание, что если у вас нет нескольких параметров с одним и тем же именем, тип StringValues не является проблемой.

Ответ 8

У меня есть лучшее решение этой проблемы,

  • запрос является членом абстрактного класса ControllerBase
  • GetSearchParams() - это метод расширения, созданный в помощнике ниже. класс.

var searchparams = await Request.GetSearchParams();

Я создал статический класс с несколькими методами расширения

public static class HttpRequestExtension
{
  public static async Task<SearchParams> GetSearchParams(this HttpRequest request)
        {
            var parameters = await request.TupledParameters();

            try
            {
                for (var i = 0; i < parameters.Count; i++)
                {
                    if (parameters[i].Item1 == "_count" && parameters[i].Item2 == "0")
                    {
                        parameters[i] = new Tuple<string, string>("_summary", "count");
                    }
                }
                var searchCommand = SearchParams.FromUriParamList(parameters);
                return searchCommand;
            }
            catch (FormatException formatException)
            {
                throw new FhirException(formatException.Message, OperationOutcome.IssueType.Invalid, OperationOutcome.IssueSeverity.Fatal, HttpStatusCode.BadRequest);
            }
        }



public static async Task<List<Tuple<string, string>>> TupledParameters(this HttpRequest request)
{
        var list = new List<Tuple<string, string>>();


        var query = request.Query;
        foreach (var pair in query)
        {
            list.Add(new Tuple<string, string>(pair.Key, pair.Value));
        }

        if (!request.HasFormContentType)
        {
            return list;
        }
        var getContent = await request.ReadFormAsync();

        if (getContent == null)
        {
            return list;
        }
        foreach (var key in getContent.Keys)
        {
            if (!getContent.TryGetValue(key, out StringValues values))
            {
                continue;
            }
            foreach (var value in values)
            {
                list.Add(new Tuple<string, string>(key, value));
            }
        }
        return list;
    }
}

таким образом вы можете легко получить доступ ко всем параметрам поиска. Надеюсь, это поможет многим разработчикам :)

Ответ 9

в ядре .net, если вы хотите получить доступ к строке запроса в нашем представлении, используйте его как

@Context.Request.Query["yourKey"]

если мы находимся в месте, где @Context недоступен, мы можем ввести его как

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@if (HttpContextAccessor.HttpContext.Request.Query.Keys.Contains("yourKey"))
{
      <text>do something </text>
}

также для печенья

HttpContextAccessor.HttpContext.Request.Cookies["DeniedActions"]