Asp.net core 将数组传递给asp net核心web api操作方法HttpGet

Asp.net core 将数组传递给asp net核心web api操作方法HttpGet,asp.net-core,.net-core,asp.net-core-webapi,Asp.net Core,.net Core,Asp.net Core Webapi,我正在尝试向我的操作方法发送一个整数数组。代码如下所示: [HttpGet] public async Task<IActionResult> ServicesByCategoryIds([FromQuery] int[] ids) { var services = await _accountsUow.GetServiceProfilesByCategoryIdsAsync(ids); return Ok(services);

我正在尝试向我的操作方法发送一个整数数组。代码如下所示:

[HttpGet]
    public async Task<IActionResult> ServicesByCategoryIds([FromQuery] int[] ids)
    {
        var services = await _accountsUow.GetServiceProfilesByCategoryIdsAsync(ids);
        return Ok(services);
    }
[HttpGet]
公共异步任务服务ByCategoryId([FromQuery]int[]ID)
{
var services=await_accountsUow.getServiceProfilesByCategoryIDAsync(ids);
返回Ok(服务);
}
我这样称呼这个方法:

但是当我调用此方法时,即使我在查询字符串中传递ID,也总是得到一个空数组。我正在使用.NETCore2.1

我在谷歌上搜索到的所有信息都表明,这实际上就是这样做的。 这里有我遗漏的东西吗


谢谢大家!

我创建了一个新的web api类,只有一个操作

[Produces("application/json")]
[Route("api/accounts")]
public class AccountsController : Controller
{
    [HttpGet]
    [Route("servicesbycategoryids")]
    public IActionResult ServicesByCategoryIds([FromQuery] int[] ids)
    {
        return Ok();
    }
}
然后使用与您相同的url:


它正在工作。

绑定
数组失败
参数是已记录的
Asp.Net Core 2.1
下的已知问题

对于临时解决方案,您可以如下所示设置
FromQuery Name属性

        [HttpGet()]
    [Route("ServicesByCategoryIds")]
    public async Task<IActionResult> ServicesByCategoryIds([FromQuery(Name = "ids")]int[] ids)
    {            
        return Ok();
    }
[HttpGet()]
[路线(“ServicesByCategoryId”)]
公共异步任务服务ByCategoryId([FromQuery(Name=“ids”)]int[]ids)
{            
返回Ok();
}

您可以实现自定义模型绑定器,并将ID作为URI的一部分,而不是在查询字符串中

您的端点可能如下所示: /api/账户/服务分类ID/(1,2)

公共类ArrayModelBinder:IModelBinder
{
公共任务BindModelAsync(ModelBindingContext bindingContext)
{
//我们的绑定器只适用于可枚举类型
如果(!bindingContext.ModelMetadata.IsEnumerableType)
{
bindingContext.Result=ModelBindingResult.Failed();
返回Task.CompletedTask;
}
//通过值提供程序获取输入值
var value=bindingContext.ValueProvider
.GetValue(bindingContext.ModelName).ToString();
//如果该值为null或空白,则返回null
if(string.IsNullOrWhiteSpace(value))
{
bindingContext.Result=ModelBindingResult.Success(null);
返回Task.CompletedTask;
}
//该值不是null或空格,
//模型的类型是可枚举的。
//获取可枚举的类型和转换器

var elementType=bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0]; var converter=TypeDescriptor.GetConverter(elementType); //将值列表中的每个项转换为可枚举类型 var values=value.Split(新[]{,“},StringSplitOptions.RemoveEmptyEntries) .Select(x=>converter.ConvertFromString(x.Trim())) .ToArray(); //创建该类型的数组,并将其设置为模型值 var typedValues=Array.CreateInstance(elementType,values.Length); CopyTo(typedValues,0); bindingContext.Model=类型值; //返回一个成功的结果,传入模型 bindingContext.Result=ModelBindingResult.Success(bindingContext.Model); 返回Task.CompletedTask; } }
然后在行动中使用它:

[HttpGet(({ids})”,Name=“GetAuthorCollection”)]
公共IActionResult GetAuthorCollection(
[ModelBinder(BinderType=typeof(ArrayModelBinder))]IEnumerable ID)
{
//在这里输入代码
}

这是从pluralsight课程中学到的:使用ASP.NET核心构建RESTful API与Plamen的答案略有不同

  • 数组似乎添加了一个空的
    GenericTypeArguments
  • 重命名类以避免与框架类冲突
    ArrayModelBinder
  • 根据需要对元素类型添加检查
  • 使用括号包围阵列的更多选项
公共类CustomArrayModelBinder:IModelBinder
{
公共任务BindModelAsync(ModelBindingContext bindingContext)
{
如果(!bindingContext.ModelMetadata.IsEnumerableType)
{
bindingContext.Result=ModelBindingResult.Failed();
返回Task.CompletedTask;
}
var value=bindingContext.ValueProvider
.GetValue(bindingContext.ModelName)
.ToString();
if(string.IsNullOrWhiteSpace(value))
{
bindingContext.Result=ModelBindingResult.Success(null);
返回Task.CompletedTask;
}

var elementType=bindingContext.ModelType.GetElementType()?? bindingContext.ModelType.GetTypeInfo().GenericTypeArguments.FirstOrDefault(); if(elementType==null) { bindingContext.Result=ModelBindingResult.Failed(); 返回Task.CompletedTask; } var converter=TypeDescriptor.GetConverter(elementType); var values=value.Split(“,”,StringSplitOptions.RemoveEmptyEntries) .Select(x=>converter.ConvertFromString(Clean(x))) .ToArray(); var typedValues=Array.CreateInstance(elementType,values.Length); CopyTo(typedValues,0); bindingContext.Model=类型值; bindingContext.Result=ModelBindingResult.Success(bindingContext.Model); 返回Task.CompletedTask; } 私有静态字符串清理(字符串str) { 返回str.Trim(“(”,“)”).Trim(“[”,“]”).Trim(); } }
然后与
IEnumerable一起使用

[ModelBinder(BinderType=typeof(CustomArrayModelBinder))]IEnumerable ID
... T[]ID
... IList ID
参数可以位于路径或查询中,并带有可选括号

[Route(“resources/{ids}”)]
资源/ids/1,2,3
资源/ID/(1,2,3)
资源/ids/[1,2,3]
[路线(“资源”)]
资源?ID=1,2,3
资源?ID=(1,2,3)
资源?ID=[1,2,3]
而不是[ab]使用qu
public IActionResult ServicesByCategoryIds([FromBody] int[] ids)
    "parameters": [
      {
        "name": "ids",
        "in": "body",
        "required": true,
        "schema": {
          "type": "array",
          "items": {
            "type": "integer",
            "format": "int32"
          }
        }
      }
    ],