我试图将一个整数数组发送到我的动作方法,代码如下所示:
[HttpGet]
public async Task<IActionResult> ServicesByCategoryIds([FromQuery] int[] ids)
{
var services = await _accountsUow.GetServiceProfilesByCategoryIdsAsync(ids);
return Ok(services);
}
我这样称呼方法:https://localhost:44343/api/accounts/servicesbycategoryids?ids=1&ids=2
但是当我调用这个方法时,总是得到空数组,即使我在查询字符串中传递了ids。我正在使用.net核心2.1。
我用Google搜索的所有内容都表明这实际上就是这样做的方式。 。 。这里有什么我想念的吗?
谢谢!
Array
参数的绑定失败是Asp.Net Core 2.1
下的一个已知问题,已被记录为Array or List in query string does not get parsed #7712。
对于临时解决方法,您可以像下面那样设置FromQuery Name Property
:
[HttpGet()]
[Route("ServicesByCategoryIds")]
public async Task<IActionResult> ServicesByCategoryIds([FromQuery(Name = "ids")]int[] ids)
{
return Ok();
}
我创建了一个新的web api类,只有一个动作。
[Produces("application/json")]
[Route("api/accounts")]
public class AccountsController : Controller
{
[HttpGet]
[Route("servicesbycategoryids")]
public IActionResult ServicesByCategoryIds([FromQuery] int[] ids)
{
return Ok();
}
}
然后使用与您相同的网址:
http://localhost:2443/api/accounts/servicesbycategoryids?ids=1&ids=2
这是工作。
您可以将自定义模型绑定器和ID实现为URI的一部分,而不是查询字符串中的一部分。
您的端点可能如下所示:/ api / accounts / servicesbycategoryids /(1,2)
public class ArrayModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
// Our binder works only on enumerable types
if (!bindingContext.ModelMetadata.IsEnumerableType)
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.CompletedTask;
}
// Get the inputted value through the value provider
var value = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName).ToString();
// If that value is null or whitespace, we return null
if (string.IsNullOrWhiteSpace(value))
{
bindingContext.Result = ModelBindingResult.Success(null);
return Task.CompletedTask;
}
// The value isn't null or whitespace,
// and the type of the model is enumerable.
// Get the enumerable's type, and a converter
var elementType = bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0];
var converter = TypeDescriptor.GetConverter(elementType);
// Convert each item in the value list to the enumerable type
var values = value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => converter.ConvertFromString(x.Trim()))
.ToArray();
// Create an array of that type, and set it as the Model value
var typedValues = Array.CreateInstance(elementType, values.Length);
values.CopyTo(typedValues, 0);
bindingContext.Model = typedValues;
// return a successful result, passing in the Model
bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
return Task.CompletedTask;
}
}
然后在你的行动中使用它:
[HttpGet("({ids})", Name="GetAuthorCollection")]
public IActionResult GetAuthorCollection(
[ModelBinder(BinderType = typeof(ArrayModelBinder))] IEnumerable<Guid> ids)
{
//enter code here
}
从多元化的课程中学到了这一点:使用ASP.NET Core构建RESTful API