Reputation: 11375
I'm building one RESTful API using ASP.NET Core MVC and I want to use querystring parameters to specify filtering and paging on a resource that returns a collection.
In that case, I need to read the values passed in the querystring to filter and select the results to return.
I've already found out that inside the controller Get
action accessing HttpContext.Request.Query
returns one IQueryCollection
.
The problem is that I don't know how it is used to retrieve the values. In truth, I thought the way to do was by using, for example
string page = HttpContext.Request.Query["page"]
The problem is that HttpContext.Request.Query["page"]
doesn't return a string, but a StringValues
.
Anyway, how does one use the IQueryCollection
to actually read the querystring values?
Upvotes: 292
Views: 520793
Reputation: 1
To retrieve the values from the IQueryCollection
, you can use the indexer with the parameter name.
string page = HttpContext.Request.Query["page"].ToString(); // Convert to string if necessary
You can access individual querystring parameters by their names, and then use .ToString()
to convert the StringValues
to a string if needed.
Upvotes: 0
Reputation: 1
we usually can fetch data from routing in 3 way: 1.query string 2.query params 3.hybrid
I describe query string:
exp:
[HttpGet("Home/routing")]
public IActionResult privacy(String name)
{
return ViewModel:name
}
to pass name as querystring:
url:port/Home/routing?name=Alex
Upvotes: 0
Reputation: 8588
In case you want to access QueryString inside of an asp.net core view you can do it like this:
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@if (Context.Request.Query.Keys.Any())
{
<button>--ClearFilters--</button>
}
Upvotes: 1
Reputation: 1874
Startup.cs
add this service
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
Code
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@{
var id = HttpContextAccessor.HttpContext.Request.RouteValues["id"];
if (id != null)
{
// parameter exist in your URL
}
}
Upvotes: 2
Reputation: 15991
ASP.NET Core will automatically bind form values
, route values
and query strings
by name. This means you can simply do this:
[HttpGet()]
public IActionResult Get(int page)
{ ... }
MVC will try to bind request data to the action parameters by name ... below is a list of the data sources in the order that model binding looks through them
Form values
: These are form values that go in the HTTP request using the POST method. (including jQuery POST requests).
Route values
: The set of route values provided by Routing
Query strings
: The query string part of the URI.
Source: Model Binding in ASP.NET Core
FYI, you can also combine the automatic and explicit approaches:
[HttpGet()]
public IActionResult Get(int page
, [FromQuery(Name = "page-size")] int pageSize)
{ ... }
Upvotes: 76
Reputation: 115
Maybe it helps. For get query string parameter in view
View:
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@{ Context.Request.Query["uid"]}
Startup.cs ConfigureServices :
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Upvotes: 8
Reputation: 2812
Some of the comments mention this as well, but asp net core does all this work for you.
If you have a query string that matches the name it will be available in the controller.
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
Upvotes: 2
Reputation: 519
I have a better solution for this problem,
var searchparams = await Request.GetSearchParams();
I have created a static class with few extension methods
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;
}
}
in this way you can easily access all your search parameters. I hope this will help many developers :)
Upvotes: 3
Reputation: 1779
in .net core if you want to access querystring in our view use it like
@Context.Request.Query["yourKey"]
if we are in location where @Context is not avilable we can inject it like
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@if (HttpContextAccessor.HttpContext.Request.Query.Keys.Contains("yourKey"))
{
<text>do something </text>
}
also for cookies
HttpContextAccessor.HttpContext.Request.Cookies["DeniedActions"]
Upvotes: 13
Reputation: 610
You can just create an object like this:
public class SomeQuery
{
public string SomeParameter { get; set; }
public int? SomeParameter2 { get; set; }
}
And then in controller just make something like that:
[HttpGet]
public IActionResult FindSomething([FromQuery] SomeQuery query)
{
// Your implementation goes here..
}
Even better, you can create API model from:
[HttpGet]
public IActionResult GetSomething([FromRoute] int someId, [FromQuery] SomeQuery query)
to:
[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; }
}
Upvotes: 37
Reputation: 315
StringValues
is an array of strings. You can get your string value by providing an index, e.g. HttpContext.Request.Query["page"][0]
.
Upvotes: 25
Reputation: 692
Here is a code sample I've used (with a .NET Core view):
@{
Microsoft.Extensions.Primitives.StringValues queryVal;
if (Context.Request.Query.TryGetValue("yourKey", out queryVal) &&
queryVal.FirstOrDefault() == "yourValue")
{
}
}
Upvotes: 49
Reputation: 16502
You can use [FromQuery]
to bind a particular model to the querystring:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
e.g.
[HttpGet()]
public IActionResult Get([FromQuery(Name = "page")] string page)
{...}
Upvotes: 260
Reputation: 2491
IQueryCollection
has a TryGetValue()
on it that returns a value with the given key. So, if you had a query parameter called someInt
, you could use it like so:
var queryString = httpContext.Request.Query;
StringValues someInt;
queryString.TryGetValue("someInt", out someInt);
var daRealInt = int.Parse(someInt);
Notice that unless you have multiple parameters of the same name, the StringValues
type is not an issue.
Upvotes: 12
Reputation: 1038800
You could use the ToString method on IQueryCollection
which will return the desired value if a single page
parameter is specified:
string page = HttpContext.Request.Query["page"].ToString();
if there are multiple values like ?page=1&page=2
then the result of the ToString call will be 1,2
But as @mike-g suggested in his answer you would better use model binding and not directly accessing the HttpContext.Request.Query
object.
Upvotes: 179