asp.net-web-api - 如何使用 Web API 中的属性路由通过 URI 发送数组?

标签 asp.net-web-api routes asp.net-web-api-routing

我正在关注 article on Attribute Routing in Web API 2尝试通过 URI 发送数组:

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

这在使用基于约定的路由时有效:

http://localhost:24144/api/set/copy/?ids=1&ids=2&ids=3

但是使用属性路由它不再起作用 - 我得到 404 not found。

如果我尝试这个:

http://localhost:24144/api/set/copy/1

然后它就起作用了 - 我得到一个只有一个元素的数组。

如何以这种方式使用属性路由?

最佳答案

您注意到的行为与操作选择和模型绑定(bind)更相关,而不是与属性路由相关。

如果您希望“ids”来自查询字符串,请像下面这样修改您的路由模板(因为您定义它的方式使得“ids”在 uri 路径中是强制的):

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

看看你的第二个问题,你是否希望接受 uri 本身内的 id 列表,例如 api/set/copy/[1,2,3]?如果是,我认为 Web api 没有对这种模型绑定(bind)的内置支持。

您可以实现如下所示的自定义参数绑定(bind)来实现它(我猜测还有其他更好的方法来实现这一点,例如通过模型绑定(bind)器和值提供程序,但我不太了解它们......所以您可能可以也需要探索这些选项):

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

示例:

[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<string> ids = idsAsString.Split(',');
        ids = ids.Where(str => !string.IsNullOrEmpty(str));

        IEnumerable<int> idList = ids.Select(strId =>
            {
                if (string.IsNullOrEmpty(strId)) return -1;

                return Convert.ToInt32(strId);

            }).ToArray();

        SetValue(actionContext, idList);

        TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
        tcs.SetResult(null);
        return tcs.Task;
    }
}

关于asp.net-web-api - 如何使用 Web API 中的属性路由通过 URI 发送数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17798281/

相关文章:

azure - webapi 不适用于 azure

c# - 如何创建异步 web-api Controller 操作

php - Laravel - 路线不起作用(未找到)

asp.net-core - 如何重定向到 ASP.NET Core WebAPI 中的操作?

c# - 找到多个与请求 http post 方法匹配的操作

asp.net-web-api - Skype for Business UCWA 和 Web API 与 Office365

azure - 如何使 Azure Web Api 项目 REST 端点仅可用于 Azure 虚拟网络

ruby-on-rails - Rails - 缺少路由助手前缀

angularjs - 表达 res.json() 到 Angular $http.get() 格式问题

ASP.NET 核心 Web API : Routing by method name?