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

C# 如何使用ASP.NET Core从查询字符串中读取值?,c#,http,asp.net-core,query-string,.net-core,C#,Http,Asp.net Core,Query String,.net Core,我正在使用ASP.NET核心MVC构建一个RESTful API,我想使用querystring参数来指定对返回集合的资源的过滤和分页 在这种情况下,我需要读取querystring中传递的值以进行筛选,并选择要返回的结果 我已经发现在控制器Getaction访问HttpContext.Request.Query中返回一个IQueryCollection 问题是我不知道如何使用它来检索值。事实上,我认为这样做的方法是使用,例如 string page = HttpContext.Request.

我正在使用ASP.NET核心MVC构建一个RESTful API,我想使用querystring参数来指定对返回集合的资源的过滤和分页

在这种情况下,我需要读取querystring中传递的值以进行筛选,并选择要返回的结果

我已经发现在控制器
Get
action访问
HttpContext.Request.Query
中返回一个
IQueryCollection

问题是我不知道如何使用它来检索值。事实上,我认为这样做的方法是使用,例如

string page = HttpContext.Request.Query["page"]
问题是
HttpContext.Request.Query[“page”]
不返回字符串,而是返回
StringValues


无论如何,如何使用
IQueryCollection
实际读取查询字符串值?

您可以使用
[FromQuery]
将特定模型绑定到查询字符串:

e、 g


您可以在
IQueryCollection
上使用ToString方法,如果指定了单个
页面
参数,该方法将返回所需的值:

string page = HttpContext.Request.Query["page"].ToString();
如果存在多个值,如
?page=1和page=2
,则ToString调用的结果将是
1,2


但是正如@mike-g在他的回答中建议的那样,您最好使用模型绑定,而不要直接访问
HttpContext.Request.Query
对象。

IQueryCollection
上有一个
TryGetValue()
,它用给定的键返回一个值。因此,如果您有一个名为
someInt
的查询参数,您可以这样使用它:

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

请注意,除非您有多个同名参数,否则
StringValues
类型不是问题。

以下是我使用的代码示例(带有.NET核心视图):


ASP.NET Core将按名称自动绑定
表单值
路由值
查询字符串
。这意味着您可以简单地执行以下操作:

[HttpGet()]
公共IActionResult Get(整版页)
{ ... }

MVC将尝试按名称将请求数据绑定到操作参数。。。下面是数据源的列表,按照模型绑定查看它们的顺序排列

  • 表单值
    :这些是使用POST方法进入HTTP请求的表单值。(包括jQuery POST请求)

  • 路由值
    :路由提供的路由值集

  • 查询字符串
    :URI的查询字符串部分

  • 资料来源:


    仅供参考,您还可以将自动和显式方法结合起来:

    [HttpGet()]
    公共IActionResult Get(int页
    ,[FromQuery(Name=“page size”)]int pageSize)
    { ... }
    
    StringValues
    是一个。您可以通过在.net core中提供索引来获取字符串值,例如
    HttpContext.Request.Query[“page”][0]

    ,如果您想在我们的视图中访问querystring,请像这样使用它

    @Context.Request.Query["yourKey"]
    
    如果我们处于@Context不可用的位置,我们可以像这样注入它

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

    您可以创建如下所示的对象:

    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)
    
    致:


    对于这个问题我有一个更好的解决方案

    • 请求是抽象类ControllerBase的成员
    • GetSearchParams()是在bellow helper中创建的扩展方法 班级
    var searchparams=wait 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;
        }
    }
    
    公共静态类HttpRequestExtension
    {
    公共静态异步任务GetSearchParams(此HttpRequest请求)
    {
    var parameters=wait request.TupledParameters();
    尝试
    {
    对于(var i=0;i

    通过这种方式,您可以轻松访问所有搜索参数。我希望这将帮助许多开发人员:)

    一些评论也提到了这一点,但asp net core为您完成了所有这些工作

    如果您有一个与名称匹配的查询字符串,它将在控制器中可用

    输出:

    123

    是的,这很有效,也许有帮助。 用于获取视图中的查询字符串参数

    视图:

    Startup.cs配置服务:

    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
    services.TryAddSingleton();
    
  • Startup.cs
    添加此服务
    services.AddSingleton()
  • 您的视图添加注入
    @injec
    
    [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; }
    }
    
    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;
        }
    }
    
    [HttpPost]
    [Route("some-endpoint/{someValue}")]
    public IActionResult SomeEndpointMethod(int someValue, string someQueryString)
        {
            Debug.WriteLine(someValue);
            Debug.WriteLine(someQueryString);
            return Ok();
        }
    
    @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
    @{ Context.Request.Query["uid"]}
    
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
    @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
    @{
        var id = HttpContextAccessor.HttpContext.Request.RouteValues["id"];
    
        if (id != null)
        {
            // parameter exist in your URL 
        }
    }