简体   繁体   English

如何使用 ASP.NET Core 从查询字符串中读取值?

[英]How to read values from the querystring with ASP.NET Core?

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.我正在使用 ASP.NET Core MVC 构建一个 RESTful API,我想使用查询字符串参数来指定对返回集合的资源的过滤和分页。

In that case, I need to read the values passed in the querystring to filter and select the results to return.在这种情况下,我需要读取查询字符串中传递的值进行过滤,并 select 返回结果。

I've already found out that inside the controller Get action accessing HttpContext.Request.Query returns one IQueryCollection .我已经发现在 controller Get操作中访问HttpContext.Request.Query返回一个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 .问题是HttpContext.Request.Query["page"]不返回字符串,而是返回StringValues

Anyway, how does one use the IQueryCollection to actually read the querystring values?无论如何,如何使用IQueryCollection实际读取查询字符串值?

You can use [FromQuery] to bind a particular model to the querystring:您可以使用[FromQuery]将特定模型绑定到查询字符串:

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding

eg例如

[HttpGet()]
public IActionResult Get([FromQuery(Name = "page")] string page)
{...}

You could use the ToString method on IQueryCollection which will return the desired value if a single page parameter is specified:您可以在IQueryCollection上使用 ToString 方法,如果指定了单个page参数,它将返回所需的值:

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如果有多个值,如?page=1&page=2那么 ToString 调用的结果将是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.但是正如@mike-g 在他的回答中建议的那样,您最好使用模型绑定而不是直接访问HttpContext.Request.Query对象。

ASP.NET Core will automatically bind form values , route values and query strings by name. ASP.NET Core 将自动按名称绑定form valuesroute valuesquery strings 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 MVC 将尝试按名称将请求数据绑定到操作参数......下面是数据源列表,按模型绑定查看它们的顺序排列

  1. Form values : These are form values that go in the HTTP request using the POST method. Form values :这些是使用 POST 方法进入 HTTP 请求的表单值。 (including jQuery POST requests). (包括 jQuery POST 请求)。

  2. Route values : The set of route values provided by Routing Route values : Routing 提供的一组路由值

  3. Query strings : The query string part of the URI. Query strings :URI 的查询字符串部分。

Source: Model Binding in ASP.NET Core来源: 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)
{ ... }

Here is a code sample I've used (with a .NET Core view):这是我使用过的代码示例(带有 .NET Core 视图):

@{
    Microsoft.Extensions.Primitives.StringValues queryVal;

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

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:更好的是,您可以从以下位置创建 API 模型:

[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; }
}

StringValues is an array of strings . StringValues是一个字符串数组 You can get your string value by providing an index, eg HttpContext.Request.Query["page"][0] .您可以通过提供索引来获取字符串值,例如HttpContext.Request.Query["page"][0]

IQueryCollection has a TryGetValue() on it that returns a value with the given key. IQueryCollection有一个TryGetValue() ,它返回具有给定键的值。 So, if you had a query parameter called someInt , you could use it like so:因此,如果您有一个名为someInt的查询参数,您可以像这样使用它:

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.请注意,除非您有多个同名参数,否则StringValues类型不是问题。

in .net core if you want to access querystring in our view use it like在 .net core 中,如果您想在我们的视图中访问查询字符串,请使用它

@Context.Request.Query["yourKey"]

if we are in location where @Context is not avilable we can inject it like如果我们在 @Context 不可用的位置,我们可以像这样注入它

@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"]

Maybe it helps.也许它有帮助。 For get query string parameter in view在视图中获取查询字符串参数

View:看法:

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@{ Context.Request.Query["uid"]}

Startup.cs ConfigureServices : Startup.cs 配置服务:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

I have a better solution for this problem,对于这个问题,我有一个更好的解决方案,

  • request is a member of abstract class ControllerBase request 是抽象类 ControllerBase 的成员
  • GetSearchParams() is an extension method created in bellow helper class. GetSearchParams() 是在 bellow helper 类中创建的扩展方法。

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 :)我希望这会帮助许多开发人员:)

  1. Startup.cs add this service services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); Startup.cs添加这个服务services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  2. Your view add inject @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor您的视图添加注入@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
  3. get your value得到你的价值

Code代码

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
@{
    var id = HttpContextAccessor.HttpContext.Request.RouteValues["id"];

    if (id != null)
    {
        // parameter exist in your URL 
    }
}

Some of the comments mention this as well, but asp net core does all this work for you.一些评论也提到了这一点,但 asp net core 会为您完成所有这些工作。

If you have a query string that matches the name it will be available in the controller.如果您有一个与名称匹配的查询字符串,它将在控制器中可用。

https://myapi/some-endpoint/123?someQueryString=YayThisWorkshttps://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 123

YayThisWorks YayThisWorks

In case you want to access QueryString inside of an asp.net core view you can do it like this:如果您想在 asp.net 核心视图中访问 QueryString,您可以这样做:

@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor

@if (Context.Request.Query.Keys.Any())
{
    <button>--ClearFilters--</button>
}

we usually can fetch data from routing in 3 way: 1.query string 2.query params 3.hybrid我们通常可以通过 3 种方式从路由中获取数据: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 url:port/Home/routing?name=Alex

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM