Как читать значения из строки запроса с помощью 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
для фактического чтения значений запроса?
Ответы
Ответ 1
Вы можете использовать [FromQuery]
для привязки определенной модели к querystring:
https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
например
[HttpGet()]
public IActionResult Get([FromQuery(Name = "page")] string page)
{...}
Ответ 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 попытается связать данные запроса с параметрами действия по имени... ниже приведен список источников данных в том порядке, в котором просматривается привязка модели
-
Form values
: это значения формы, которые входят в HTTP-запрос с использованием метода POST. (включая запросы POST JQuery).
-
Route values
: набор значений маршрута, предоставляемых маршрутизацией
-
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"]