C# 具有多个参数的webapi方法的自定义模型绑定器
我拥有的 我有一个api控制器(ASP.NET Core MVC),使用以下方法:C# 具有多个参数的webapi方法的自定义模型绑定器,c#,asp.net-core,asp.net-core-mvc,C#,Asp.net Core,Asp.net Core Mvc,我拥有的 我有一个api控制器(ASP.NET Core MVC),使用以下方法: [HttpPost] [Route("delete")] public Task<ActionResult> SomeAction(Guid[] ids, UserToken userToken, CancellationToken cancellationToken) { .... } 已将活页夹提供程序添加到服务: services.AddMvc(options => {
[HttpPost]
[Route("delete")]
public Task<ActionResult> SomeAction(Guid[] ids, UserToken userToken, CancellationToken cancellationToken)
{
....
}
已将活页夹提供程序添加到服务:
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new UserTokenBinderProvider());
});
问题
服务器加载时,我收到以下异常(invalidooperationexception
):
…'SomeAction'有多个参数被指定或推断为从请求体绑定。每个动作只能从主体绑定一个参数。检查以下参数,并使用“FromQueryAttribute”指定从查询绑定,“FromRouteAttribute”指定从路由绑定,使用“FromBodyAttribute”指定从正文绑定的参数:
Guid[]ID,
用户令牌用户令牌
MVC似乎忽略了我对UserToken
类型的自定义绑定器,并尝试使用默认方法绑定它。
你知道为什么吗
编辑
在这里收到答复后,打开了一个修改ASP.NET核心文档的窗口 存在
[ApiController]
属性引入了操作参数。启动时,操作模型约定针对所有检测到的控制器操作运行,并推断绑定源。对于复杂类型,例如Guid[]
和UserToken
参数,此推断选择请求主体作为源-就像您自己将[FromBody]
添加到这两个参数中一样,如下所示:
public Task<ActionResult> SomeAction(
[FromBody] Guid[] ids,
[FromBody] UserToken userToken,
CancellationToken cancellationToken)
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new UserTokenBinderProvider());
options.ModelMetadataDetailsProviders.Add(
new BindingSourceMetadataProvider(typeof(UserToken), BindingSource.Special));
});
这种方法的最大缺点是,UserToken
类依赖于MVC属性,而MVC属性可能不是您想要的。那么,还有更好的吗
现在,您可能想知道为什么我没有为上面的CancellationToken
参数显示[FromBody]
。这是否意味着CancellationToken
会得到特殊待遇。将BindingSourceMetadataProvider
添加到将其绑定源指定为的mvcopions
实例中。当动作模型约定运行并试图推断绑定源时,它会看到绑定源已经设置好,并将其保留
要解决您的问题,请为您的UserToken
类型添加BindingSourceMetadataProvider
,并使用BindingSource.Special
,如下所示:
public Task<ActionResult> SomeAction(
[FromBody] Guid[] ids,
[FromBody] UserToken userToken,
CancellationToken cancellationToken)
services.AddMvc(options =>
{
options.ModelBinderProviders.Insert(0, new UserTokenBinderProvider());
options.ModelMetadataDetailsProviders.Add(
new BindingSourceMetadataProvider(typeof(UserToken), BindingSource.Special));
});
尝试添加([FromBody]Guid[]ids,[FromBody]UserToken UserToken)可能是相关的。@Nenad,UserToken有一个自定义模型绑定器,[FromBody]有什么好处?