zor*_*nov 6 .net-core asp.net-core asp.net-core-webapi
我试图将整数数组发送到我的操作方法,代码看起来像这样:
[HttpGet]
public async Task<IActionResult> ServicesByCategoryIds([FromQuery] int[] ids)
{
var services = await _accountsUow.GetServiceProfilesByCategoryIdsAsync(ids);
return Ok(services);
}
Run Code Online (Sandbox Code Playgroud)
我这样调用该方法:https:// localhost:44343 / api / accounts / servicesbycategoryids?ids = 1&ids = 2
但是,即使我在查询字符串中传递ID时,调用此方法时总会得到一个空数组。我正在使用.net core 2.1。
我搜索过的所有内容都表明这实际上是完成的方式。。。我在这里缺少什么吗?
谢谢!
Array参数绑定失败是一个已知问题,在Asp.Net Core 2.1该问题下,未记录查询字符串中的数组或列表,而未对其进行解析#7712。
对于临时的解决方法,您可以设置FromQuery Name Property如下所示:
[HttpGet()]
[Route("ServicesByCategoryIds")]
public async Task<IActionResult> ServicesByCategoryIds([FromQuery(Name = "ids")]int[] ids)
{
return Ok();
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个新的 Web api 类,只有一个操作。
[Produces("application/json")]
[Route("api/accounts")]
public class AccountsController : Controller
{
[HttpGet]
[Route("servicesbycategoryids")]
public IActionResult ServicesByCategoryIds([FromQuery] int[] ids)
{
return Ok();
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用与您相同的网址:
http://localhost:2443/api/accounts/servicesbycategoryids?ids=1&ids=2
这是工作。
Plamen 的回答略有不同。
GenericTypeArguments所以添加了GetElementType()ArrayModelBinder。public class CustomArrayModelBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (!bindingContext.ModelMetadata.IsEnumerableType)
{
bindingContext.Result = ModelBindingResult.Failed();
return Task.CompletedTask;
}
var value = bindingContext.ValueProvider
.GetValue(bindingContext.ModelName)
.ToString();
if (string.IsNullOrWhiteSpace(value))
{
bindingContext.Result = ModelBindingResult.Success(null);
return Task.CompletedTask;
}
var elementType = bindingContext.ModelType.GetElementType() ??
bindingContext.ModelType.GetTypeInfo().GenericTypeArguments.FirstOrDefault();
if (elementType == null)
{
bindingContext.Result = ModelBindingResult.Failed();
return 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);
values.CopyTo(typedValues, 0);
bindingContext.Model = typedValues;
bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
return Task.CompletedTask;
}
private static string Clean(string str)
{
return str.Trim('(', ')').Trim('[', ']').Trim();
}
}
Run Code Online (Sandbox Code Playgroud)
然后与IEnumerable<T>,IList<T>或数组一起使用T[]
[ModelBinder(BinderType = typeof(CustomArrayModelBinder))] IEnumerable<T> ids
... T[] ids
... IList<T> ids
Run Code Online (Sandbox Code Playgroud)
参数可以在带有可选括号的路径或查询中。
[Route("resources/{ids}")]
resource/ids/1,2,3
resource/ids/(1,2,3)
resource/ids/[1,2,3]
[Route("resources")]
resource?ids=1,2,3
resource?ids=(1,2,3)
resource?ids=[1,2,3]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6334 次 |
| 最近记录: |