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

时间:2017-01-10 20:02:19

标签: c# http asp.net-core query-string .net-core

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

在这种情况下,我需要读取查询字符串中传递的值来过滤并选择要返回的结果。

我已经发现,在控制器Get内部访问HttpContext.Request.Query的操作会返回一个IQueryCollection

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

string page = HttpContext.Request.Query["page"]

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

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

12 个答案:

答案 0 :(得分:79)

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

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

e.g。

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

答案 1 :(得分:62)

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

string page = HttpContext.Request.Query["page"].ToString();

如果有多个值,例如?page=1&page=2,那么ToString调用的结果将为1,2

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

答案 2 :(得分:14)

ASP.NET Core会自动按名称绑定form valuesroute valuesquery strings。这意味着您可以简单地执行此操作:

[HttpGet()]
public IActionResult Get(int page)
{ ... }
  

MVC将尝试通过名称将请求数据绑定到操作参数...下面是模型绑定通过它们查找的顺序中的数据源列表

     
      
  1. Form values:这些是使用POST方法在HTTP请求中的表单值。 (包括jQuery POST请求)。

  2.   
  3. Route values:路由

  4. 提供的路由值集   
  5. Query strings:URI的查询字符串部分。

  6.   

来源:How model binding works

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

[HttpGet()]
public IActionResult Get(int page
     , [FromQuery(Name = "page-size")] int pageSize)
{ ... }

答案 3 :(得分:11)

以下是我使用的代码示例(使用.NET Core视图):

@{
    Microsoft.Extensions.Primitives.StringValues queryVal;

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

答案 4 :(得分:10)

您可以像这样创建一个对象:

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

答案 5 :(得分:6)

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

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

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

答案 6 :(得分:6)

StringValuesarray of strings。您可以通过提供索引来获取字符串值,例如HttpContext.Request.Query["page"][0]

答案 7 :(得分:4)

也许有帮助。 在视图中获取查询字符串参数

查看:

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

Startup.cs ConfigureServices:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

答案 8 :(得分:2)

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

  • request是抽象类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 :(得分:1)

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

如果查询字符串与名称匹配,它将在控制器中可用。

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();
    }

输出:

123

YayThisWorks

答案 10 :(得分:1)

  1. Startup.cs 添加此服务 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  2. 您的视图添加 inject @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
  3. 获得你的价值

代码

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

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

答案 11 :(得分:0)

.p核心中的

如果要访问我们视图中的querystring,请像

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

也用于Cookie

HttpContextAccessor.HttpContext.Request.Cookies["DeniedActions"]