Asp.net-Core

將數組傳遞給 asp net core web api 操作方法 HttpGet

  • December 6, 2021

我正在嘗試向我的操作方法發送一個整數數組,程式碼如下所示:

[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

但是當我呼叫這個方法時總是得到一個空數組,即使我在查詢字元串中傳遞了 id。我正在使用 .net 核心 2.1。

我用Google搜尋的所有內容都表明這實際上是這樣做的。. . 我在這裡缺少什麼嗎?

謝謝!

參數綁定失敗Array是一個已知問題,在該問題下Asp.Net Core 2.1已記錄查詢字元串中的 Array 或 List 無法解析 #7712

對於臨時解決方法,您可以設置FromQuery Name Property如下:

       [HttpGet()]
   [Route("ServicesByCategoryIds")]
   public async Task<IActionResult> ServicesByCategoryIds([FromQuery(Name = "ids")]int[] ids)
   {            
       return Ok();
   }

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

然後與IEnumerable<T>,IList<T>或數組一起使用T[]

[ModelBinder(BinderType = typeof(CustomArrayModelBinder))] IEnumerable<T> ids
                                                      ... T[] ids
                                                      ... IList<T> ids

參數可以在路徑或帶有可選括號的查詢中。

[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]

引用自:https://stackoverflow.com/questions/51300861