Buduję jeden interfejs API RESTful przy użyciu ASP.NET Core MVC i chcę użyć parametrów kwerendy, aby określić filtrowanie i stronicowanie zasobu, który zwraca kolekcję.
W takim przypadku muszę odczytać wartości przekazane w kwerendzie do filtrowania i wybrać wyniki do zwrócenia.
Dowiedziałem się już, że wewnątrz Get
akcji kontrolera dostęp HttpContext.Request.Query
zwraca jeden IQueryCollection
.
Problem w tym, że nie wiem, w jaki sposób jest używany do pobierania wartości. Prawdę mówiąc, pomyślałem, że należy na przykład użyć
string page = HttpContext.Request.Query["page"]
Problem polega na tym, HttpContext.Request.Query["page"]
że nie zwraca ciągu, ale plik StringValues
.
W każdym razie, w jaki sposób można użyć, IQueryCollection
aby faktycznie odczytać wartości zapytania?
c#
http
asp.net-core
query-string
.net-core
user1620696
źródło
źródło
Odpowiedzi:
Możesz użyć
[FromQuery]
do powiązania określonego modelu z querystringiem:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
na przykład
[HttpGet()] public IActionResult Get([FromQuery(Name = "page")] string page) {...}
źródło
[FromQuery]
atrybut może również zostać pominięty, ponieważ wiązanie .net będzie domyślnie sprawdzać wszystkie dane wejściowe formularza i parametry zapytania o adres URL, z wyjątkiem tego, że masz jakiś powód, aby ograniczyć jego źródło.Możesz użyć metody ToString,
IQueryCollection
która zwróci żądaną wartość, jeślipage
zostanie określony pojedynczy parametr:string page = HttpContext.Request.Query["page"].ToString();
jeśli istnieje wiele wartości, takich jak
?page=1&page=2
to, wynik wywołania ToString będzie1,2
Ale jak @ mike-g zasugerował w swojej odpowiedzi, lepiej byłoby użyć wiązania modelu, a nie bezpośredniego dostępu do
HttpContext.Request.Query
obiektu.źródło
Rdzeń ASP.NET automatycznie wiążą
form values
,route values
iquery strings
po imieniu. Oznacza to, że możesz po prostu zrobić to:[HttpGet()] public IActionResult Get(int page) { ... }
Źródło: powiązanie modelu w ASP.NET Core
FYI, możesz również połączyć podejście automatyczne i jawne:
[HttpGet()] public IActionResult Get(int page , [FromQuery(Name = "page-size")] int pageSize) { ... }
źródło
Oto przykładowy kod, którego użyłem (z widokiem .NET Core):
@{ Microsoft.Extensions.Primitives.StringValues queryVal; if (Context.Request.Query.TryGetValue("yourKey", out queryVal) && queryVal.FirstOrDefault() == "yourValue") { } }
źródło
Możesz po prostu utworzyć taki obiekt:
public class SomeQuery { public string SomeParameter { get; set; } public int? SomeParameter2 { get; set; } }
A potem w kontrolerze po prostu zrób coś takiego:
[HttpGet] public IActionResult FindSomething([FromQuery] SomeQuery query) { // Your implementation goes here.. }
Co więcej, możesz stworzyć model API z:
[HttpGet] public IActionResult GetSomething([FromRoute] int someId, [FromQuery] SomeQuery query)
do:
[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; } }
źródło
StringValues
jest tablicą ciągów . Możesz uzyskać wartość ciągu, podając indeks, npHttpContext.Request.Query["page"][0]
.źródło
IQueryCollection
ma na sobie znakTryGetValue()
, który zwraca wartość z podanym kluczem. Tak więc, jeśli masz parametr zapytania o nazwiesomeInt
, możesz go użyć w następujący sposób:var queryString = httpContext.Request.Query; StringValues someInt; queryString.TryGetValue("someInt", out someInt); var daRealInt = int.Parse(someInt);
Zauważ, że jeśli nie masz wielu parametrów o tej samej nazwie,
StringValues
typ nie stanowi problemu.źródło
w .net core, jeśli chcesz uzyskać dostęp do querystringu, użyj go jak
@Context.Request.Query["yourKey"]
jeśli jesteśmy w miejscu, w którym @Context nie jest dostępny, możemy go wstrzyknąć
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor @if (HttpContextAccessor.HttpContext.Request.Query.Keys.Contains("yourKey")) { <text>do something </text> }
także dla plików cookie
HttpContextAccessor.HttpContext.Request.Cookies["DeniedActions"]
źródło
Może to pomaga. Aby uzyskać parametr ciągu zapytania w widoku
Widok:
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor @{ Context.Request.Query["uid"]}
Startup.cs ConfigureServices:
źródło
Mam lepsze rozwiązanie tego problemu,
var searchparams = await Request.GetSearchParams();
Utworzyłem klasę statyczną z kilkoma metodami rozszerzającymi
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; } }
w ten sposób możesz łatwo uzyskać dostęp do wszystkich parametrów wyszukiwania. Mam nadzieję, że pomoże to wielu programistom :)
źródło
Niektóre komentarze również o tym wspominają, ale asp net core wykonuje całą tę pracę za Ciebie.
Jeśli masz ciąg zapytania, który pasuje do nazwy, będzie on dostępny w kontrolerze.
https: // myapi / some-endpoint / 123? someQueryString = YayThisWorks
[HttpPost] [Route("some-endpoint/{someValue}")] public IActionResult SomeEndpointMethod(int someValue, string someQueryString) { Debug.WriteLine(someValue); Debug.WriteLine(someQueryString); return Ok(); }
Ouputs:
123
YayThisWorks
źródło