How to send an array via a URI using Attribute Routing in Web API?

后端 未结 1 1428
攒了一身酷
攒了一身酷 2021-02-14 09:27

I\'m following the article on Attribute Routing in Web API 2 to try to send an array via URI:

[HttpPost(\"api/set/copy/{ids}\")]
public HttpResponseMessage CopyS         


        
1条回答
  •  情书的邮戳
    2021-02-14 10:15

    The behavior you are noticing is more related to Action selection & Model binding rather than Attribute Routing.

    If you are expecting 'ids' to come from query string, then modify your route template like below(because the way you have defined it makes 'ids' mandatory in the uri path):

    [HttpPost("api/set/copy")]
    

    Looking at your second question, are you looking to accept a list of ids within the uri itself, like api/set/copy/[1,2,3]? if yes, I do not think web api has in-built support for this kind of model binding.

    You could implement a custom parameter binding like below to achieve it though(I am guessing there are other better ways to achieve this like via modelbinders and value providers, but i am not much aware of them...so you could probably need to explore those options too):

    [HttpPost("api/set/copy/{ids}")]
    public HttpResponseMessage CopySet([CustomParamBinding]int[] ids)
    

    Example:

    [AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
    public class CustomParamBindingAttribute : ParameterBindingAttribute
    {
        public override HttpParameterBinding GetBinding(HttpParameterDescriptor paramDesc)
        {
            return new CustomParamBinding(paramDesc);
        }
    }
    
    public class CustomParamBinding : HttpParameterBinding
    {
        public CustomParamBinding(HttpParameterDescriptor paramDesc) : base(paramDesc) { }
    
        public override bool WillReadBody
        {
            get
            {
                return false;
            }
        }
    
        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, 
                                                        CancellationToken cancellationToken)
        {
            //TODO: VALIDATION & ERROR CHECKS
            string idsAsString = actionContext.Request.GetRouteData().Values["ids"].ToString();
    
            idsAsString = idsAsString.Trim('[', ']');
    
            IEnumerable ids = idsAsString.Split(',');
            ids = ids.Where(str => !string.IsNullOrEmpty(str));
    
            IEnumerable idList = ids.Select(strId =>
                {
                    if (string.IsNullOrEmpty(strId)) return -1;
    
                    return Convert.ToInt32(strId);
    
                }).ToArray();
    
            SetValue(actionContext, idList);
    
            TaskCompletionSource tcs = new TaskCompletionSource();
            tcs.SetResult(null);
            return tcs.Task;
        }
    }
    
        

    0 讨论(0)
    提交回复
    热议问题