C# ASP.NET核心传递可枚举的对象以在控制器上获取操作

C# ASP.NET核心传递可枚举的对象以在控制器上获取操作,c#,asp.net,rest,http,asp.net-core,C#,Asp.net,Rest,Http,Asp.net Core,我试图在ASP.NET Core 2.2中定义一个控制器操作 棘手的部分是,我希望它是一个GET端点,并且它必须接收的数据是一个自定义对象的集合。以下是我的示例代码: [Route("api/example")] [ApiController] public class ExampleController : ControllerBase { [HttpGet("getData")] [ProducesResponseType(typeof(int), StatusCodes.S

我试图在ASP.NET Core 2.2中定义一个控制器操作

棘手的部分是,我希望它是一个GET端点,并且它必须接收的数据是一个自定义对象的集合。以下是我的示例代码:

[Route("api/example")]
[ApiController]
public class ExampleController : ControllerBase
{
    [HttpGet("getData")]
    [ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetMarketData([FromQuery] MyObject[] queryData)
    {
        return this.Ok(0);
    }
}

public class MyObject
{
    public int A { get; set; }

    public int B { get; set; }
}
然而,我似乎无法让它发挥作用

(向URL发送请求时,不会解析对象,我在控制器中收到一个空数组)

我不确定这是否是最好的方法,也许我需要改变绑定数据的位置

我唯一关心的是能够接收MyObject的数组(或某种集合),我可以处理并返回响应。我还希望这是一个GET请求,毕竟,我正在尝试查询这个API并从中获取数据

我知道我可以使用[FromBody]属性使其工作,但据我所知get请求不应该使用body


非常感谢您提供的任何帮助。

由于没有集合类型的默认活页夹,因此无法使用,您必须使用自定义活页夹。我自己实现了一个通用阵列模型绑定器,如下所示:

//通用数组模型绑定器
公共类ArrayModelBinder:IModelBinder{
公共任务BindModelAsync(ModelBindingContext bindingContext){
if(bindingContext.ModelMetadata.IsEnumerableType){
var value=bindingContext.ValueProvider.GetValue(bindingContext.ModelName.ToString();
如果(!string.IsNullOrEmpty(值)){
var elementType=typeof(TType);
var typeConverter=TypeDescriptor.GetConverter(elementType);
var splittedValues=value.Split(新[]{,“},StringSplitOptions.RemoveEmptyEntries);
var values=splittedValues.Select(t=>typeConverter.ConvertFromString(t.Trim()).ToArray();
var typedValues=Array.CreateInstance(elementType,values.Length);
CopyTo(typedValues,0);
bindingContext.Model=类型值;
返回SuccessBinding(bindingContext,TypedValue);
}
返回SuccessBinding(bindingContext,null);
}
返回FailedBinding(bindingContext);
}
私有静态任务成功绑定(ModelBindingContext、数组类型值){
bindingContext.Result=ModelBindingResult.Success(类型值);
返回Task.CompletedTask;
}
私有静态任务失败绑定(ModelBindingContext bindingContext){
bindingContext.Result=ModelBindingResult.Failed();
返回Task.CompletedTask;
}
要在您的操作中使用它,您只需使用以下代码:


public async Task<IActionResult> GetMarketData([ModelBinder(BinderType = typeof(ArrayModelBinder<object>))] MyObject[] queryData)
{
    return this.Ok(0);
}


公共异步任务GetMarketData([ModelBinder(BinderType=typeof(ArrayModelBinder))]MyObject[]queryData)
{
返回此。确定(0);
}

我在我自己的库的repo中有此实现和其他内容的源代码请随意查看

您的GET请求必须按照以下方式构造:

GET: /api/example/getData?queryData[0].A=1&queryData[0].B=2&queryData[1].A=3

与使用
s:)时的模型绑定非常相似。

您的查询字符串应该如下所示:

/TestMe?queryData[0].A=1&queryData[0].B=1&queryData[1].A=2&queryData[1].B=2
如果您的代码如下所示:

public class MyObject
{
    public int A { get; set; }

    public int B { get; set; }
}

[Route("/TestMe")]
public IActionResult TestMe([FromQuery] MyObject[] queryData)
{ 
    return Json(queryData);
}
请注意,
[FromQuery]
甚至不是必需的

public class MyObject
{
    public int A { get; set; }

    public int B { get; set; }
}

[Route("/TestMe")]
public IActionResult TestMe([FromQuery] MyObject[] queryData)
{ 
    return Json(queryData);
}